<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
		<title>Offline</title>
		<style type="text/css">
			body {
				font-family: "Lucida Sans", "Lucida Grande", Helvetica, Arial, Verdana, sans-serif;
				font-size: 12px;
				letter-spacing: -0.5px;
			}
			/**
			 *-----------------------------------------------------------------------
			 * TYPOGRAPHY
			 *-----------------------------------------------------------------------
			 */

			a {
				color: #888888;
				text-decoration: none;
			}
			a:hover {
				color: #f56d21;
			}
			a:visited {
				color: #65436f;
			}
			h1 {
				font-size: 24px;
			}
			h2 {
				font-size: 18px;
				font-weight: bold;
			}
			h3 {
				color: #000;
				font-size: 16px;
			}
			h4 {
				color: #878b95;
				font-size: 12px;
			}
			h5 {
				color: #878b95;
				font-size: 11px;
			}
			p {
				font-size: 12px;
				line-height: 19px;
			}
			h1 + h4, h2 + h4, h3 + h5 {
				margin-top: 2px;
			}
			h4 + p {
				margin-top: 12px;
			}
			h5 + p {
				margin-top: 6px;
			}
			p strong {
				font-weight: bold;
				display: block;
				line-height: 16px;
				margin-bottom: 4px;
			}
			/**
			 *-----------------------------------------------------------------------
			 * HEADER
			 *-----------------------------------------------------------------------
			 */

			#header {
				background: url('../images/page-header-bg.png') repeat-x top left #2d323e;
				height: 58px;
				text-align: center;
				overflow: hidden;
				width: 100%;
			}
			#header .logo {
				float: left;
			}
			#header .page-title {
				margin-left: -108px;
			}
			/**
			 *-----------------------------------------------------------------------
			 * BODY
			 *-----------------------------------------------------------------------
			 */

			#body, #detail {
				margin: 100px auto;
				padding: 20px 0;
				width: 573px;
				border: 1px solid #e3e4e5;
			}
			#body ul.cols, #detail ul.cols {
				overflow: hidden;
				width: 100%;
			}
			#body ul.cols li.left, #body ul.cols li.right, #detail ul.cols li.left, #detail ul.cols li.right {
				float: left;
				overflow: hidden;
			}
			#reload {
				padding-right: 10px;
				padding-left: 16px;
				padding-top: 2px;
				float: right;
				background: url('../images/arrow-rotate-clockwise.png');
				background-repeat: no-repeat;
			}
			.shadow {
				-webkit-box-shadow: 0px 0px 8px #999;
				-moz-box-shadow: 0px 0px 8px #999;
				box-shadow: 0px 0px 8px #999;
			}
		</style>
		<script type="text/javascript">
			/*  Prototype JavaScript framework, version 1.6.1
			 *  (c) 2005-2009 Sam Stephenson
			 *
			 *  Prototype is freely distributable under the terms of an MIT-style license.
			 *  For details, see the Prototype web site: http://www.prototypejs.org/
			 *
			 *--------------------------------------------------------------------------*/

			var Prototype = {
				Version : '1.6.1',

				Browser : (function() {
					var ua = navigator.userAgent;
					var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
					return {
						IE : !!window.attachEvent && !isOpera,
						Opera : isOpera,
						WebKit : ua.indexOf('AppleWebKit/') > -1,
						Gecko : ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
						MobileSafari : /Apple.*Mobile.*Safari/.test(ua)
					}
				})(),

				BrowserFeatures : {
					XPath : !!document.evaluate,
					SelectorsAPI : !!document.querySelector,
					ElementExtensions : (function() {
						var constructor = window.Element || window.HTMLElement;
						return !!(constructor && constructor.prototype);
					})(),
					SpecificElementExtensions : (function() {
						if( typeof window.HTMLDivElement !== 'undefined')
							return true;

						var div = document.createElement('div');
						var form = document.createElement('form');
						var isSupported = false;

						if(div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
							isSupported = true;
						}
						div = form = null;

						return isSupported;
					})()
				},

				ScriptFragment : '<script[^>]*>([\\S\\s]*?)<\/script>',
				JSONFilter : /^\/\*-secure-([\s\S]*)\*\/\s*$/,

				emptyFunction : function() {
				},
				K : function(x) {
					return x
				}
			};

			if(Prototype.Browser.MobileSafari)
				Prototype.BrowserFeatures.SpecificElementExtensions = false;

			var Abstract = { };

			var Try = {
				these : function() {
					var returnValue;

					for(var i = 0, length = arguments.length; i < length; i++) {
						var lambda = arguments[i];
						try {
							returnValue = lambda();
							break;
						} catch (e) {
						}
					}

					return returnValue;
				}
			};

			/* Based on Alex Arnell's inheritance implementation. */

			var Class = (function() {
				function subclass() {
				};

				function create() {
					var parent = null, properties = $A(arguments);
					if(Object.isFunction(properties[0]))
						parent = properties.shift();

					function klass() {
						this.initialize.apply(this, arguments);
					}


					Object.extend(klass, Class.Methods);
					klass.superclass = parent;
					klass.subclasses = [];

					if(parent) {
						subclass.prototype = parent.prototype;
						klass.prototype = new subclass;
						parent.subclasses.push(klass);
					}

					for(var i = 0; i < properties.length; i++)
					klass.addMethods(properties[i]);

					if(!klass.prototype.initialize)
						klass.prototype.initialize = Prototype.emptyFunction;

					klass.prototype.constructor = klass;
					return klass;
				}

				function addMethods(source) {
					var ancestor = this.superclass && this.superclass.prototype;
					var properties = Object.keys(source);

					if(!Object.keys({
						toString : true
					}).length) {
						if(source.toString != Object.prototype.toString)
							properties.push("toString");
						if(source.valueOf != Object.prototype.valueOf)
							properties.push("valueOf");
					}

					for(var i = 0, length = properties.length; i < length; i++) {
						var property = properties[i], value = source[property];
						if(ancestor && Object.isFunction(value) && value.argumentNames().first() == "$super") {
							var method = value;
							value = (function(m) {
								return function() {
									return ancestor[m].apply(this, arguments);
								};
							})(property).wrap(method);

							value.valueOf = method.valueOf.bind(method);
							value.toString = method.toString.bind(method);
						}
						this.prototype[property] = value;
					}

					return this;
				}

				return {
					create : create,
					Methods : {
						addMethods : addMethods
					}
				};
			})(); (function() {

				var _toString = Object.prototype.toString;

				function extend(destination, source) {
					for(var property in source)
					destination[property] = source[property];
					return destination;
				}

				function inspect(object) {
					try {
						if(isUndefined(object))
							return 'undefined';
						if(object === null)
							return 'null';
						return object.inspect ? object.inspect() : String(object);
					} catch (e) {
						if( e instanceof RangeError)
							return '...';
						throw e;
					}
				}

				function toJSON(object) {
					var type = typeof object;
					switch (type) {
						case 'undefined':
						case 'function':
						case 'unknown':
							return;
						case 'boolean':
							return object.toString();
					}

					if(object === null)
						return 'null';
					if(object.toJSON)
						return object.toJSON();
					if(isElement(object))
						return;

					var results = [];
					for(var property in object) {
						var value = toJSON(object[property]);
						if(!isUndefined(value))
							results.push(property.toJSON() + ': ' + value);
					}

					return '{' + results.join(', ') + '}';
				}

				function toQueryString(object) {
					return $H(object).toQueryString();
				}

				function toHTML(object) {
					return object && object.toHTML ? object.toHTML() : String.interpret(object);
				}

				function keys(object) {
					var results = [];
					for(var property in object)
					results.push(property);
					return results;
				}

				function values(object) {
					var results = [];
					for(var property in object)
					results.push(object[property]);
					return results;
				}

				function clone(object) {
					return extend({ }, object);
				}

				function isElement(object) {
					return !!(object && object.nodeType == 1);
				}

				function isArray(object) {
					return _toString.call(object) == "[object Array]";
				}

				function isHash(object) {
					return object instanceof Hash;
				}

				function isFunction(object) {
					return typeof object === "function";
				}

				function isString(object) {
					return _toString.call(object) == "[object String]";
				}

				function isNumber(object) {
					return _toString.call(object) == "[object Number]";
				}

				function isUndefined(object) {
					return typeof object === "undefined";
				}

				extend(Object, {
					extend : extend,
					inspect : inspect,
					toJSON : toJSON,
					toQueryString : toQueryString,
					toHTML : toHTML,
					keys : keys,
					values : values,
					clone : clone,
					isElement : isElement,
					isArray : isArray,
					isHash : isHash,
					isFunction : isFunction,
					isString : isString,
					isNumber : isNumber,
					isUndefined : isUndefined
				});
			})();
			Object.extend(Function.prototype, (function() {
				var slice = Array.prototype.slice;

				function update(array, args) {
					var arrayLength = array.length, length = args.length;
					while(length--)
					array[arrayLength + length] = args[length];
					return array;
				}

				function merge(array, args) {
					array = slice.call(array, 0);
					return update(array, args);
				}

				function argumentNames() {
					var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1].replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '').replace(/\s+/g, '').split(',');
					return names.length == 1 && !names[0] ? [] : names;
				}

				function bind(context) {
					if(arguments.length < 2 && Object.isUndefined(arguments[0]))
						return this;
					var __method = this, args = slice.call(arguments, 1);
					return function() {
						var a = merge(args, arguments);
						return __method.apply(context, a);
					}
				}

				function bindAsEventListener(context) {
					var __method = this, args = slice.call(arguments, 1);
					return function(event) {
						var a = update([event || window.event], args);
						return __method.apply(context, a);
					}
				}

				function curry() {
					if(!arguments.length)
						return this;
					var __method = this, args = slice.call(arguments, 0);
					return function() {
						var a = merge(args, arguments);
						return __method.apply(this, a);
					}
				}

				function delay(timeout) {
					var __method = this, args = slice.call(arguments, 1);
					timeout = timeout * 1000
					return window.setTimeout(function() {
						return __method.apply(__method, args);
					}, timeout);
				}

				function defer() {
					var args = update([0.01], arguments);
					return this.delay.apply(this, args);
				}

				function wrap(wrapper) {
					var __method = this;
					return function() {
						var a = update([__method.bind(this)], arguments);
						return wrapper.apply(this, a);
					}
				}

				function methodize() {
					if(this._methodized)
						return this._methodized;
					var __method = this;
					return this._methodized = function() {
						var a = update([this], arguments);
						return __method.apply(null, a);
					};
				}

				return {
					argumentNames : argumentNames,
					bind : bind,
					bindAsEventListener : bindAsEventListener,
					curry : curry,
					delay : delay,
					defer : defer,
					wrap : wrap,
					methodize : methodize
				}
			})());

			Date.prototype.toJSON = function() {
				return '"' + this.getUTCFullYear() + '-' + (this.getUTCMonth() + 1).toPaddedString(2) + '-' + this.getUTCDate().toPaddedString(2) + 'T' + this.getUTCHours().toPaddedString(2) + ':' + this.getUTCMinutes().toPaddedString(2) + ':' + this.getUTCSeconds().toPaddedString(2) + 'Z"';
			};

			RegExp.prototype.match = RegExp.prototype.test;

			RegExp.escape = function(str) {
				return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
			};
			var PeriodicalExecuter = Class.create({
				initialize : function(callback, frequency) {
					this.callback = callback;
					this.frequency = frequency;
					this.currentlyExecuting = false;

					this.registerCallback();
				},
				registerCallback : function() {
					this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
				},
				execute : function() {
					this.callback(this);
				},
				stop : function() {
					if(!this.timer)
						return;
					clearInterval(this.timer);
					this.timer = null;
				},
				onTimerEvent : function() {
					if(!this.currentlyExecuting) {
						try {
							this.currentlyExecuting = true;
							this.execute();
							this.currentlyExecuting = false;
						} catch(e) {
							this.currentlyExecuting = false;
							throw e;
						}
					}
				}
			});
			Object.extend(String, {
				interpret : function(value) {
					return value == null ? '' : String(value);
				},
				specialChar : {
					'\b' : '\\b',
					'\t' : '\\t',
					'\n' : '\\n',
					'\f' : '\\f',
					'\r' : '\\r',
					'\\' : '\\\\'
				}
			});

			Object.extend(String.prototype, (function() {

				function prepareReplacement(replacement) {
					if(Object.isFunction(replacement))
						return replacement;
					var template = new Template(replacement);
					return function(match) {
						return template.evaluate(match)
					};
				}

				function gsub(pattern, replacement) {
					var result = '', source = this, match;
					replacement = prepareReplacement(replacement);

					if(Object.isString(pattern))
						pattern = RegExp.escape(pattern);

					if(!(pattern.length || pattern.source)) {
						replacement = replacement('');
						return replacement + source.split('').join(replacement) + replacement;
					}

					while(source.length > 0) {
						if( match = source.match(pattern)) {
							result += source.slice(0, match.index);
							result += String.interpret(replacement(match));
							source = source.slice(match.index + match[0].length);
						} else {result += source, source = '';
						}
					}
					return result;
				}

				function sub(pattern, replacement, count) {
					replacement = prepareReplacement(replacement);
					count = Object.isUndefined(count) ? 1 : count;

					return this.gsub(pattern, function(match) {
						if(--count < 0)
							return match[0];
						return replacement(match);
					});
				}

				function scan(pattern, iterator) {
					this.gsub(pattern, iterator);
					return String(this);
				}

				function truncate(length, truncation) {
					length = length || 30;
					truncation = Object.isUndefined(truncation) ? '...' : truncation;
					return this.length > length ? this.slice(0, length - truncation.length) + truncation : String(this);
				}

				function strip() {
					return this.replace(/^\s+/, '').replace(/\s+$/, '');
				}

				function stripTags() {
					return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
				}

				function stripScripts() {
					return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
				}

				function extractScripts() {
					var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
					var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
					return (this.match(matchAll) || []).map(function(scriptTag) {
						return (scriptTag.match(matchOne) || ['', ''])[1];
					});
				}

				function evalScripts() {
					return this.extractScripts().map(function(script) {
						return eval(script)
					});
				}

				function escapeHTML() {
					return this.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
				}

				function unescapeHTML() {
					return this.stripTags().replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&');
				}

				function toQueryParams(separator) {
					var match = this.strip().match(/([^?#]*)(#.*)?$/);
					if(!match)
						return { };

					return match[1].split(separator || '&').inject({ }, function(hash, pair) {
						if((pair = pair.split('='))[0]) {
							var key = decodeURIComponent(pair.shift());
							var value = pair.length > 1 ? pair.join('=') : pair[0];
							if(value != undefined)
								value = decodeURIComponent(value);

							if( key in hash) {
								if(!Object.isArray(hash[key]))
									hash[key] = [hash[key]];
								hash[key].push(value);
							} else
								hash[key] = value;
						}
						return hash;
					});
				}

				function toArray() {
					return this.split('');
				}

				function succ() {
					return this.slice(0, this.length - 1) + String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
				}

				function times(count) {
					return count < 1 ? '' : new Array(count + 1).join(this);
				}

				function camelize() {
					var parts = this.split('-'), len = parts.length;
					if(len == 1)
						return parts[0];

					var camelized = this.charAt(0) == '-' ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1) : parts[0];

					for(var i = 1; i < len; i++)
					camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);

					return camelized;
				}

				function capitalize() {
					return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
				}

				function underscore() {
					return this.replace(/::/g, '/').replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2').replace(/([a-z\d])([A-Z])/g, '$1_$2').replace(/-/g, '_').toLowerCase();
				}

				function dasherize() {
					return this.replace(/_/g, '-');
				}

				function inspect(useDoubleQuotes) {
					var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
						if( character in String.specialChar) {
							return String.specialChar[character];
						}
						return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
					});
					if(useDoubleQuotes)
						return '"' + escapedString.replace(/"/g, '\\"') + '"';
					return "'" + escapedString.replace(/'/g, '\\\'') + "'";
				}

				function toJSON() {
					return this.inspect(true);
				}

				function unfilterJSON(filter) {
					return this.replace(filter || Prototype.JSONFilter, '$1');
				}

				function isJSON() {
					var str = this;
					if(str.blank())
						return false;
					str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
					return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
				}

				function evalJSON(sanitize) {
					var json = this.unfilterJSON();
					try {
						if(!sanitize || json.isJSON())
							return eval('(' + json + ')');
					} catch (e) {
					}
					throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
				}

				function include(pattern) {
					return this.indexOf(pattern) > -1;
				}

				function startsWith(pattern) {
					return this.indexOf(pattern) === 0;
				}

				function endsWith(pattern) {
					var d = this.length - pattern.length;
					return d >= 0 && this.lastIndexOf(pattern) === d;
				}

				function empty() {
					return this == '';
				}

				function blank() {
					return /^\s*$/.test(this);
				}

				function interpolate(object, pattern) {
					return new Template(this, pattern).evaluate(object);
				}

				return {
					gsub : gsub,
					sub : sub,
					scan : scan,
					truncate : truncate,
					strip : String.prototype.trim ? String.prototype.trim : strip,
					stripTags : stripTags,
					stripScripts : stripScripts,
					extractScripts : extractScripts,
					evalScripts : evalScripts,
					escapeHTML : escapeHTML,
					unescapeHTML : unescapeHTML,
					toQueryParams : toQueryParams,
					parseQuery : toQueryParams,
					toArray : toArray,
					succ : succ,
					times : times,
					camelize : camelize,
					capitalize : capitalize,
					underscore : underscore,
					dasherize : dasherize,
					inspect : inspect,
					toJSON : toJSON,
					unfilterJSON : unfilterJSON,
					isJSON : isJSON,
					evalJSON : evalJSON,
					include : include,
					startsWith : startsWith,
					endsWith : endsWith,
					empty : empty,
					blank : blank,
					interpolate : interpolate
				};
			})());

			var Template = Class.create({
				initialize : function(template, pattern) {
					this.template = template.toString();
					this.pattern = pattern || Template.Pattern;
				},
				evaluate : function(object) {
					if(object && Object.isFunction(object.toTemplateReplacements))
						object = object.toTemplateReplacements();

					return this.template.gsub(this.pattern, function(match) {
						if(object == null)
							return (match[1] + '');

						var before = match[1] || '';
						if(before == '\\')
							return match[2];

						var ctx = object, expr = match[3];
						var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
						match = pattern.exec(expr);
						if(match == null)
							return before;

						while(match != null) {
							var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
							ctx = ctx[comp];
							if(null == ctx || '' == match[3])
								break;
							expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
							match = pattern.exec(expr);
						}

						return before + String.interpret(ctx);
					});
				}
			});
			Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;

			var $break = { };

			var Enumerable = (function() {
				function each(iterator, context) {
					var index = 0;
					try {
						this._each(function(value) {
							iterator.call(context, value, index++);
						});
					} catch (e) {
						if(e != $break)
							throw e;
					}
					return this;
				}

				function eachSlice(number, iterator, context) {
					var index = -number, slices = [], array = this.toArray();
					if(number < 1)
						return array;
					while((index += number) < array.length)
					slices.push(array.slice(index, index + number));
					return slices.collect(iterator, context);
				}

				function all(iterator, context) {
					iterator = iterator || Prototype.K;
					var result = true;
					this.each(function(value, index) {
						result = result && !!iterator.call(context, value, index);
						if(!result)
							throw $break;
					});
					return result;
				}

				function any(iterator, context) {
					iterator = iterator || Prototype.K;
					var result = false;
					this.each(function(value, index) {
						if( result = !!iterator.call(context, value, index))
							throw $break;
					});
					return result;
				}

				function collect(iterator, context) {
					iterator = iterator || Prototype.K;
					var results = [];
					this.each(function(value, index) {
						results.push(iterator.call(context, value, index));
					});
					return results;
				}

				function detect(iterator, context) {
					var result;
					this.each(function(value, index) {
						if(iterator.call(context, value, index)) {
							result = value;
							throw $break;
						}
					});
					return result;
				}

				function findAll(iterator, context) {
					var results = [];
					this.each(function(value, index) {
						if(iterator.call(context, value, index))
							results.push(value);
					});
					return results;
				}

				function grep(filter, iterator, context) {
					iterator = iterator || Prototype.K;
					var results = [];

					if(Object.isString(filter))
						filter = new RegExp(RegExp.escape(filter));

					this.each(function(value, index) {
						if(filter.match(value))
							results.push(iterator.call(context, value, index));
					});
					return results;
				}

				function include(object) {
					if(Object.isFunction(this.indexOf))
						if(this.indexOf(object) != -1)
							return true;

					var found = false;
					this.each(function(value) {
						if(value == object) {
							found = true;
							throw $break;
						}
					});
					return found;
				}

				function inGroupsOf(number, fillWith) {
					fillWith = Object.isUndefined(fillWith) ? null : fillWith;
					return this.eachSlice(number, function(slice) {
						while(slice.length < number)
						slice.push(fillWith);
						return slice;
					});
				}

				function inject(memo, iterator, context) {
					this.each(function(value, index) {
						memo = iterator.call(context, memo, value, index);
					});
					return memo;
				}

				function invoke(method) {
					var args = $A(arguments).slice(1);
					return this.map(function(value) {
						return value[method].apply(value, args);
					});
				}

				function max(iterator, context) {
					iterator = iterator || Prototype.K;
					var result;
					this.each(function(value, index) {
						value = iterator.call(context, value, index);
						if(result == null || value >= result)
							result = value;
					});
					return result;
				}

				function min(iterator, context) {
					iterator = iterator || Prototype.K;
					var result;
					this.each(function(value, index) {
						value = iterator.call(context, value, index);
						if(result == null || value < result)
							result = value;
					});
					return result;
				}

				function partition(iterator, context) {
					iterator = iterator || Prototype.K;
					var trues = [], falses = [];
					this.each(function(value, index) {
						(iterator.call(context, value, index) ? trues : falses).push(value);
					});
					return [trues, falses];
				}

				function pluck(property) {
					var results = [];
					this.each(function(value) {
						results.push(value[property]);
					});
					return results;
				}

				function reject(iterator, context) {
					var results = [];
					this.each(function(value, index) {
						if(!iterator.call(context, value, index))
							results.push(value);
					});
					return results;
				}

				function sortBy(iterator, context) {
					return this.map(function(value, index) {
						return {
							value : value,
							criteria : iterator.call(context, value, index)
						};
					}).sort(function(left, right) {
						var a = left.criteria, b = right.criteria;
						return a < b ? -1 : a > b ? 1 : 0;
					}).pluck('value');
				}

				function toArray() {
					return this.map();
				}

				function zip() {
					var iterator = Prototype.K, args = $A(arguments);
					if(Object.isFunction(args.last()))
						iterator = args.pop();

					var collections = [this].concat(args).map($A);
					return this.map(function(value, index) {
						return iterator(collections.pluck(index));
					});
				}

				function size() {
					return this.toArray().length;
				}

				function inspect() {
					return '#<Enumerable:' + this.toArray().inspect() + '>';
				}

				return {
					each : each,
					eachSlice : eachSlice,
					all : all,
					every : all,
					any : any,
					some : any,
					collect : collect,
					map : collect,
					detect : detect,
					findAll : findAll,
					select : findAll,
					filter : findAll,
					grep : grep,
					include : include,
					member : include,
					inGroupsOf : inGroupsOf,
					inject : inject,
					invoke : invoke,
					max : max,
					min : min,
					partition : partition,
					pluck : pluck,
					reject : reject,
					sortBy : sortBy,
					toArray : toArray,
					entries : toArray,
					zip : zip,
					size : size,
					inspect : inspect,
					find : detect
				};
			})();
			function $A(iterable) {
				if(!iterable)
					return [];
				if('toArray' in  Object(iterable))
					return iterable.toArray();
				var length = iterable.length || 0, results = new Array(length);
				while(length--)
				results[length] = iterable[length];
				return results;
			}

			function $w(string) {
				if(!Object.isString(string))
					return [];
				string = string.strip();
				return string ? string.split(/\s+/) : [];
			}


			Array.from = $A; (function() {
				var arrayProto = Array.prototype, slice = arrayProto.slice, _each = arrayProto.forEach;
				// use native browser JS 1.6 implementation if available

				function each(iterator) {
					for(var i = 0, length = this.length; i < length; i++)iterator(this[i]);
				}

				if(!_each)
					_each = each;

				function clear() {
					this.length = 0;
					return this;
				}

				function first() {
					return this[0];
				}

				function last() {
					return this[this.length - 1];
				}

				function compact() {
					return this.select(function(value) {
						return value != null;
					});
				}

				function flatten() {
					return this.inject([], function(array, value) {
						if(Object.isArray(value))
							return array.concat(value.flatten());
						array.push(value);
						return array;
					});
				}

				function without() {
					var values = slice.call(arguments, 0);
					return this.select(function(value) {
						return !values.include(value);
					});
				}

				function reverse(inline) {
					return (inline !== false ? this : this.toArray())._reverse();
				}

				function uniq(sorted) {
					return this.inject([], function(array, value, index) {
						if(0 == index || ( sorted ? array.last() != value : !array.include(value)))
							array.push(value);
						return array;
					});
				}

				function intersect(array) {
					return this.uniq().findAll(function(item) {
						return array.detect(function(value) {
							return item === value
						});
					});
				}

				function clone() {
					return slice.call(this, 0);
				}

				function size() {
					return this.length;
				}

				function inspect() {
					return '[' + this.map(Object.inspect).join(', ') + ']';
				}

				function toJSON() {
					var results = [];
					this.each(function(object) {
						var value = Object.toJSON(object);
						if(!Object.isUndefined(value))
							results.push(value);
					});
					return '[' + results.join(', ') + ']';
				}

				function indexOf(item, i) {
					i || ( i = 0);
					var length = this.length;
					if(i < 0)
						i = length + i;
					for(; i < length; i++)
					if(this[i] === item)
						return i;
					return -1;
				}

				function lastIndexOf(item, i) {
					i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
					var n = this.slice(0, i).reverse().indexOf(item);
					return (n < 0) ? n : i - n - 1;
				}

				function concat() {
					var array = slice.call(this, 0), item;
					for(var i = 0, length = arguments.length; i < length; i++) {
						item = arguments[i];
						if(Object.isArray(item) && !('callee' in item)) {
							for(var j = 0, arrayLength = item.length; j < arrayLength; j++)
							array.push(item[j]);
						} else {
							array.push(item);
						}
					}
					return array;
				}


				Object.extend(arrayProto, Enumerable);

				if(!arrayProto._reverse)
					arrayProto._reverse = arrayProto.reverse;

				Object.extend(arrayProto, {
					_each : _each,
					clear : clear,
					first : first,
					last : last,
					compact : compact,
					flatten : flatten,
					without : without,
					reverse : reverse,
					uniq : uniq,
					intersect : intersect,
					clone : clone,
					toArray : clone,
					size : size,
					inspect : inspect,
					toJSON : toJSON
				});

				var CONCAT_ARGUMENTS_BUGGY = (function() {
					return [].concat(arguments)[0][0] !== 1;
				})(1, 2)

				if(CONCAT_ARGUMENTS_BUGGY)
					arrayProto.concat = concat;

				if(!arrayProto.indexOf)
					arrayProto.indexOf = indexOf;
				if(!arrayProto.lastIndexOf)
					arrayProto.lastIndexOf = lastIndexOf;
			})();
			function $H(object) {
				return new Hash(object);
			};

			var Hash = Class.create(Enumerable, (function() {
				function initialize(object) {
					this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
				}

				function _each(iterator) {
					for(var key in this._object) {
						var value = this._object[key], pair = [key, value];
						pair.key = key;
						pair.value = value;
						iterator(pair);
					}
				}

				function set(key, value) {
					return this._object[key] = value;
				}

				function get(key) {
					if(this._object[key] !== Object.prototype[key])
						return this._object[key];
				}

				function unset(key) {
					var value = this._object[key];
					delete this._object[key];
					return value;
				}

				function toObject() {
					return Object.clone(this._object);
				}

				function keys() {
					return this.pluck('key');
				}

				function values() {
					return this.pluck('value');
				}

				function index(value) {
					var match = this.detect(function(pair) {
						return pair.value === value;
					});
					return match && match.key;
				}

				function merge(object) {
					return this.clone().update(object);
				}

				function update(object) {
					return new Hash(object).inject(this, function(result, pair) {
						result.set(pair.key, pair.value);
						return result;
					});
				}

				function toQueryPair(key, value) {
					if(Object.isUndefined(value))
						return key;
					return key + '=' + encodeURIComponent(String.interpret(value));
				}

				function toQueryString() {
					return this.inject([], function(results, pair) {
						var key = encodeURIComponent(pair.key), values = pair.value;

						if(values && typeof values == 'object') {
							if(Object.isArray(values))
								return results.concat(values.map(toQueryPair.curry(key)));
						} else
							results.push(toQueryPair(key, values));
						return results;
					}).join('&');
				}

				function inspect() {
					return '#<Hash:{' + this.map(function(pair) {
						return pair.map(Object.inspect).join(': ');
					}).join(', ') + '}>';
				}

				function toJSON() {
					return Object.toJSON(this.toObject());
				}

				function clone() {
					return new Hash(this);
				}

				return {
					initialize : initialize,
					_each : _each,
					set : set,
					get : get,
					unset : unset,
					toObject : toObject,
					toTemplateReplacements : toObject,
					keys : keys,
					values : values,
					index : index,
					merge : merge,
					update : update,
					toQueryString : toQueryString,
					inspect : inspect,
					toJSON : toJSON,
					clone : clone
				};
			})());

			Hash.from = $H;
			Object.extend(Number.prototype, (function() {
				function toColorPart() {
					return this.toPaddedString(2, 16);
				}

				function succ() {
					return this + 1;
				}

				function times(iterator, context) {
					$R(0, this, true).each(iterator, context);
					return this;
				}

				function toPaddedString(length, radix) {
					var string = this.toString(radix || 10);
					return '0'.times(length - string.length) + string;
				}

				function toJSON() {
					return isFinite(this) ? this.toString() : 'null';
				}

				function abs() {
					return Math.abs(this);
				}

				function round() {
					return Math.round(this);
				}

				function ceil() {
					return Math.ceil(this);
				}

				function floor() {
					return Math.floor(this);
				}

				return {
					toColorPart : toColorPart,
					succ : succ,
					times : times,
					toPaddedString : toPaddedString,
					toJSON : toJSON,
					abs : abs,
					round : round,
					ceil : ceil,
					floor : floor
				};
			})());

			function $R(start, end, exclusive) {
				return new ObjectRange(start, end, exclusive);
			}

			var ObjectRange = Class.create(Enumerable, (function() {
				function initialize(start, end, exclusive) {
					this.start = start;
					this.end = end;
					this.exclusive = exclusive;
				}

				function _each(iterator) {
					var value = this.start;
					while(this.include(value)) {
						iterator(value);
						value = value.succ();
					}
				}

				function include(value) {
					if(value < this.start)
						return false;
					if(this.exclusive)
						return value < this.end;
					return value <= this.end;
				}

				return {
					initialize : initialize,
					_each : _each,
					include : include
				};
			})());

			var Ajax = {
				getTransport : function() {
					return Try.these(function() {
						return new XMLHttpRequest()
					}, function() {
						return new ActiveXObject('Msxml2.XMLHTTP')
					}, function() {
						return new ActiveXObject('Microsoft.XMLHTTP')
					}) || false;
				},
				activeRequestCount : 0
			};

			Ajax.Responders = {
				responders : [],

				_each : function(iterator) {
					this.responders._each(iterator);
				},
				register : function(responder) {
					if(!this.include(responder))
						this.responders.push(responder);
				},
				unregister : function(responder) {
					this.responders = this.responders.without(responder);
				},
				dispatch : function(callback, request, transport, json) {
					this.each(function(responder) {
						if(Object.isFunction(responder[callback])) {
							try {
								responder[callback].apply(responder, [request, transport, json]);
							} catch (e) {
							}
						}
					});
				}
			};

			Object.extend(Ajax.Responders, Enumerable);

			Ajax.Responders.register({
				onCreate : function() {
					Ajax.activeRequestCount++
				},
				onComplete : function() {
					Ajax.activeRequestCount--
				}
			});
			Ajax.Base = Class.create({
				initialize : function(options) {
					this.options = {
						method : 'post',
						asynchronous : true,
						contentType : 'application/x-www-form-urlencoded',
						encoding : 'UTF-8',
						parameters : '',
						evalJSON : true,
						evalJS : true
					};
					Object.extend(this.options, options || { });

					this.options.method = this.options.method.toLowerCase();

					if(Object.isString(this.options.parameters))
						this.options.parameters = this.options.parameters.toQueryParams();
					else if(Object.isHash(this.options.parameters))
						this.options.parameters = this.options.parameters.toObject();
				}
			});
			Ajax.Request = Class.create(Ajax.Base, {
				_complete : false,

				initialize : function($super, url, options) {
					$super(options);
					this.transport = Ajax.getTransport();
					this.request(url);
				},
				request : function(url) {
					this.url = url;
					this.method = this.options.method;
					var params = Object.clone(this.options.parameters);

					if(!['get', 'post'].include(this.method)) {
						params['_method'] = this.method;
						this.method = 'post';
					}

					this.parameters = params;

					if( params = Object.toQueryString(params)) {
						if(this.method == 'get')
							this.url += (this.url.include('?') ? '&' : '?') + params;
						else if(/Konqueror|Safari|KHTML/.test(navigator.userAgent))
							params += '&_=';
					}

					try {
						var response = new Ajax.Response(this);
						if(this.options.onCreate)
							this.options.onCreate(response);
						Ajax.Responders.dispatch('onCreate', this, response);

						this.transport.open(this.method.toUpperCase(), this.url, this.options.asynchronous);

						if(this.options.asynchronous)
							this.respondToReadyState.bind(this).defer(1);

						this.transport.onreadystatechange = this.onStateChange.bind(this);
						this.setRequestHeaders();

						this.body = this.method == 'post' ? (this.options.postBody || params) : null;
						this.transport.send(this.body);

						/* Force Firefox to handle ready state 4 for synchronous requests */
						if(!this.options.asynchronous && this.transport.overrideMimeType)
							this.onStateChange();

					} catch (e) {
						this.dispatchException(e);
					}
				},
				onStateChange : function() {
					var readyState = this.transport.readyState;
					if(readyState > 1 && !((readyState == 4) && this._complete))
						this.respondToReadyState(this.transport.readyState);
				},
				setRequestHeaders : function() {
					var headers = {
						'X-Requested-With' : 'XMLHttpRequest',
						'X-Prototype-Version' : Prototype.Version,
						'Accept' : 'text/javascript, text/html, application/xml, text/xml, */*'
					};

					if(this.method == 'post') {
						headers['Content-type'] = this.options.contentType + (this.options.encoding ? '; charset=' + this.options.encoding : '');

						/* Force "Connection: close" for older Mozilla browsers to work
						 * around a bug where XMLHttpRequest sends an incorrect
						 * Content-length header. See Mozilla Bugzilla #246651.
						 */
						if(this.transport.overrideMimeType && (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
							headers['Connection'] = 'close';
					}

					if( typeof this.options.requestHeaders == 'object') {
						var extras = this.options.requestHeaders;

						if(Object.isFunction(extras.push))
							for(var i = 0, length = extras.length; i < length; i += 2)
							headers[extras[i]] = extras[i + 1];
						else
							$H(extras).each(function(pair) {
								headers[pair.key] = pair.value
							});
					}

					for(var name in headers)
					this.transport.setRequestHeader(name, headers[name]);
				},
				success : function() {
					var status = this.getStatus();
					return !status || (status >= 200 && status < 300);
				},
				getStatus : function() {
					try {
						return this.transport.status || 0;
					} catch (e) {
						return 0
					}
				},
				respondToReadyState : function(readyState) {
					var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);

					if(state == 'Complete') {
						try {
							this._complete = true; (this.options['on' + response.status] || this.options['on' + (this.success() ? 'Success' : 'Failure')] || Prototype.emptyFunction)(response, response.headerJSON);
						} catch (e) {
							this.dispatchException(e);
						}

						var contentType = response.getHeader('Content-type');
						if(this.options.evalJS == 'force' || (this.options.evalJS && this.isSameOrigin() && contentType && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
							this.evalResponse();
					}

					try {(this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
						Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
					} catch (e) {
						this.dispatchException(e);
					}

					if(state == 'Complete') {
						this.transport.onreadystatechange = Prototype.emptyFunction;
					}
				},
				isSameOrigin : function() {
					var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
					return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
						protocol : location.protocol,
						domain : document.domain,
						port : location.port ? ':' + location.port : ''
					}));
				},
				getHeader : function(name) {
					try {
						return this.transport.getResponseHeader(name) || null;
					} catch (e) {
						return null;
					}
				},
				evalResponse : function() {
					try {
						return eval((this.transport.responseText || '').unfilterJSON());
					} catch (e) {
						this.dispatchException(e);
					}
				},
				dispatchException : function(exception) {(this.options.onException || Prototype.emptyFunction)(this, exception);
					Ajax.Responders.dispatch('onException', this, exception);
				}
			});

			Ajax.Request.Events = ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];

			Ajax.Response = Class.create({
				initialize : function(request) {
					this.request = request;
					var transport = this.transport = request.transport, readyState = this.readyState = transport.readyState;

					if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
						this.status = this.getStatus();
						this.statusText = this.getStatusText();
						this.responseText = String.interpret(transport.responseText);
						this.headerJSON = this._getHeaderJSON();
					}

					if(readyState == 4) {
						var xml = transport.responseXML;
						this.responseXML = Object.isUndefined(xml) ? null : xml;
						this.responseJSON = this._getResponseJSON();
					}
				},
				status : 0,

				statusText : '',

				getStatus : Ajax.Request.prototype.getStatus,

				getStatusText : function() {
					try {
						return this.transport.statusText || '';
					} catch (e) {
						return ''
					}
				},
				getHeader : Ajax.Request.prototype.getHeader,

				getAllHeaders : function() {
					try {
						return this.getAllResponseHeaders();
					} catch (e) {
						return null
					}
				},
				getResponseHeader : function(name) {
					return this.transport.getResponseHeader(name);
				},
				getAllResponseHeaders : function() {
					return this.transport.getAllResponseHeaders();
				},
				_getHeaderJSON : function() {
					var json = this.getHeader('X-JSON');
					if(!json)
						return null;
					json = decodeURIComponent(escape(json));
					try {
						return json.evalJSON(this.request.options.sanitizeJSON || !this.request.isSameOrigin());
					} catch (e) {
						this.request.dispatchException(e);
					}
				},
				_getResponseJSON : function() {
					var options = this.request.options;
					if(!options.evalJSON || (options.evalJSON != 'force' && !(this.getHeader('Content-type') || '').include('application/json')) || this.responseText.blank())
						return null;
					try {
						return this.responseText.evalJSON(options.sanitizeJSON || !this.request.isSameOrigin());
					} catch (e) {
						this.request.dispatchException(e);
					}
				}
			});

			Ajax.Updater = Class.create(Ajax.Request, {
				initialize : function($super, container, url, options) {
					this.container = {
						success : (container.success || container),
						failure : (container.failure || (container.success ? null : container))
					};
					options = Object.clone(options);
					var onComplete = options.onComplete;
					options.onComplete = (function(response, json) {
						this.updateContent(response.responseText);
						if(Object.isFunction(onComplete))
							onComplete(response, json);
					}).bind(this);

					$super(url, options);
				},
				updateContent : function(responseText) {
					var receiver = this.container[this.success() ? 'success' : 'failure'], options = this.options;

					if(!options.evalScripts)
						responseText = responseText.stripScripts();

					if( receiver = $(receiver)) {
						if(options.insertion) {
							if(Object.isString(options.insertion)) {
								var insertion = { };
								insertion[options.insertion] = responseText;
								receiver.insert(insertion);
							} else
								options.insertion(receiver, responseText);
						} else
							receiver.update(responseText);
					}
				}
			});

			Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
				initialize : function($super, container, url, options) {
					$super(options);
					this.onComplete = this.options.onComplete;

					this.frequency = (this.options.frequency || 2);
					this.decay = (this.options.decay || 1);

					this.updater = { };
					this.container = container;
					this.url = url;

					this.start();
				},
				start : function() {
					this.options.onComplete = this.updateComplete.bind(this);
					this.onTimerEvent();
				},
				stop : function() {
					this.updater.options.onComplete = undefined;
					clearTimeout(this.timer);
					(this.onComplete || Prototype.emptyFunction).apply(this, arguments);
				},
				updateComplete : function(response) {
					if(this.options.decay) {
						this.decay = (response.responseText == this.lastText ? this.decay * this.options.decay : 1);

						this.lastText = response.responseText;
					}
					this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
				},
				onTimerEvent : function() {
					this.updater = new Ajax.Updater(this.container, this.url, this.options);
				}
			});

			function $(element) {
				if(arguments.length > 1) {
					for(var i = 0, elements = [], length = arguments.length; i < length; i++)
					elements.push($(arguments[i]));
					return elements;
				}
				if(Object.isString(element))
					element = document.getElementById(element);
				return Element.extend(element);
			}

			if(Prototype.BrowserFeatures.XPath) {
				document._getElementsByXPath = function(expression, parentElement) {
					var results = [];
					var query = document.evaluate(expression, $(parentElement) || document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
					for(var i = 0, length = query.snapshotLength; i < length; i++)
					results.push(Element.extend(query.snapshotItem(i)));
					return results;
				};
			}

			/*--------------------------------------------------------------------------*/

			if(!window.Node)
				var Node = { };

			if(!Node.ELEMENT_NODE) {
				Object.extend(Node, {
					ELEMENT_NODE : 1,
					ATTRIBUTE_NODE : 2,
					TEXT_NODE : 3,
					CDATA_SECTION_NODE : 4,
					ENTITY_REFERENCE_NODE : 5,
					ENTITY_NODE : 6,
					PROCESSING_INSTRUCTION_NODE : 7,
					COMMENT_NODE : 8,
					DOCUMENT_NODE : 9,
					DOCUMENT_TYPE_NODE : 10,
					DOCUMENT_FRAGMENT_NODE : 11,
					NOTATION_NODE : 12
				});
			}(function(global) {

				var SETATTRIBUTE_IGNORES_NAME = (function() {
					var elForm = document.createElement("form");
					var elInput = document.createElement("input");
					var root = document.documentElement;
					elInput.setAttribute("name", "test");
					elForm.appendChild(elInput);
					root.appendChild(elForm);
					var isBuggy = elForm.elements ? ( typeof elForm.elements.test == "undefined") : null;
					root.removeChild(elForm);
					elForm = elInput = null;
					return isBuggy;
				})();

				var element = global.Element;
				global.Element = function(tagName, attributes) {
					attributes = attributes || { };
					tagName = tagName.toLowerCase();
					var cache = Element.cache;
					if(SETATTRIBUTE_IGNORES_NAME && attributes.name) {
						tagName = '<' + tagName + ' name="' + attributes.name + '">';
						delete attributes.name;
						return Element.writeAttribute(document.createElement(tagName), attributes);
					}
					if(!cache[tagName])
						cache[tagName] = Element.extend(document.createElement(tagName));
					return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
				};
				Object.extend(global.Element, element || { });
				if(element)
					global.Element.prototype = element.prototype;
			})(this);

			Element.cache = { };
			Element.idCounter = 1;

			Element.Methods = {
				visible : function(element) {
					return $(element).style.display != 'none';
				},
				toggle : function(element) {
					element = $(element);
					Element[Element.visible(element) ? 'hide' : 'show'](element);
					return element;
				},
				hide : function(element) {
					element = $(element);
					element.style.display = 'none';
					return element;
				},
				show : function(element) {
					element = $(element);
					element.style.display = '';
					return element;
				},
				remove : function(element) {
					element = $(element);
					element.parentNode.removeChild(element);
					return element;
				},
				update : (function() {

					var SELECT_ELEMENT_INNERHTML_BUGGY = (function() {
						var el = document.createElement("select"), isBuggy = true;
						el.innerHTML = "<option value=\"test\">test</option>";
						if(el.options && el.options[0]) {
							isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION";
						}
						el = null;
						return isBuggy;
					})();

					var TABLE_ELEMENT_INNERHTML_BUGGY = (function() {
						try {
							var el = document.createElement("table");
							if(el && el.tBodies) {
								el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>";
								var isBuggy = typeof el.tBodies[0] == "undefined";
								el = null;
								return isBuggy;
							}
						} catch (e) {
							return true;
						}
					})();

					var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function() {
						var s = document.createElement("script"), isBuggy = false;
						try {
							s.appendChild(document.createTextNode(""));
							isBuggy = !s.firstChild || s.firstChild && s.firstChild.nodeType !== 3;
						} catch (e) {
							isBuggy = true;
						}
						s = null;
						return isBuggy;
					})();

					function update(element, content) {
						element = $(element);

						if(content && content.toElement)
							content = content.toElement();

						if(Object.isElement(content))
							return element.update().insert(content);
						content = Object.toHTML(content);

						var tagName = element.tagName.toUpperCase();

						if(tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) {
							element.text = content;
							return element;
						}

						if(SELECT_ELEMENT_INNERHTML_BUGGY || TABLE_ELEMENT_INNERHTML_BUGGY) {
							if( tagName in Element._insertionTranslations.tags) {
								while(element.firstChild) {
									element.removeChild(element.firstChild);
								}
								Element._getContentFromAnonymousElement(tagName, content.stripScripts()).each(function(node) {
									element.appendChild(node)
								});
							} else {
								element.innerHTML = content.stripScripts();
							}
						} else {
							element.innerHTML = content.stripScripts();
						}

						content.evalScripts.bind(content).defer();
						return element;
					}

					return update;
				})(),

				replace : function(element, content) {
					element = $(element);
					if(content && content.toElement)
						content = content.toElement();
					else if(!Object.isElement(content)) {
						content = Object.toHTML(content);
						var range = element.ownerDocument.createRange();
						range.selectNode(element);
						content.evalScripts.bind(content).defer();
						content = range.createContextualFragment(content.stripScripts());
					}
					element.parentNode.replaceChild(content, element);
					return element;
				},
				insert : function(element, insertions) {
					element = $(element);

					if(Object.isString(insertions) || Object.isNumber(insertions) || Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
						insertions = {
							bottom : insertions
						};

					var content, insert, tagName, childNodes;

					for(var position in insertions) {
						content = insertions[position];
						position = position.toLowerCase();
						insert = Element._insertionTranslations[position];

						if(content && content.toElement)
							content = content.toElement();
						if(Object.isElement(content)) {
							insert(element, content);
							continue;
						}
						content = Object.toHTML(content);
						tagName = ((position == 'before' || position == 'after') ? element.parentNode : element).tagName.toUpperCase();
						childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());

						if(position == 'top' || position == 'after')
							childNodes.reverse();
						childNodes.each(insert.curry(element));

						content.evalScripts.bind(content).defer();
					}

					return element;
				},
				wrap : function(element, wrapper, attributes) {
					element = $(element);
					if(Object.isElement(wrapper))
						$(wrapper).writeAttribute(attributes || { });
					else if(Object.isString(wrapper))
						wrapper = new Element(wrapper, attributes);
					else
						wrapper = new Element('div', wrapper);
					if(element.parentNode)
						element.parentNode.replaceChild(wrapper, element);
					wrapper.appendChild(element);
					return wrapper;
				},
				inspect : function(element) {
					element = $(element);
					var result = '<' + element.tagName.toLowerCase();
					$H({
						'id' : 'id',
						'className' : 'class'
					}).each(function(pair) {
						var property = pair.first(), attribute = pair.last();
						var value = (element[property] || '').toString();
						if(value)
							result += ' ' + attribute + '=' + value.inspect(true);
					});
					return result + '>';
				},
				recursivelyCollect : function(element, property) {
					element = $(element);
					var elements = [];
					while( element = element[property])
					if(element.nodeType == 1)
						elements.push(Element.extend(element));
					return elements;
				},
				ancestors : function(element) {
					return Element.recursivelyCollect(element, 'parentNode');
				},
				descendants : function(element) {
					return Element.select(element, "*");
				},
				firstDescendant : function(element) {
					element = $(element).firstChild;
					while(element && element.nodeType != 1)
					element = element.nextSibling;
					return $(element);
				},
				immediateDescendants : function(element) {
					if(!( element = $(element).firstChild))
						return [];
					while(element && element.nodeType != 1)
					element = element.nextSibling;
					if(element)
						return [element].concat($(element).nextSiblings());
					return [];
				},
				previousSiblings : function(element) {
					return Element.recursivelyCollect(element, 'previousSibling');
				},
				nextSiblings : function(element) {
					return Element.recursivelyCollect(element, 'nextSibling');
				},
				siblings : function(element) {
					element = $(element);
					return Element.previousSiblings(element).reverse().concat(Element.nextSiblings(element));
				},
				match : function(element, selector) {
					if(Object.isString(selector))
						selector = new Selector(selector);
					return selector.match($(element));
				},
				up : function(element, expression, index) {
					element = $(element);
					if(arguments.length == 1)
						return $(element.parentNode);
					var ancestors = Element.ancestors(element);
					return Object.isNumber(expression) ? ancestors[expression] : Selector.findElement(ancestors, expression, index);
				},
				down : function(element, expression, index) {
					element = $(element);
					if(arguments.length == 1)
						return Element.firstDescendant(element);
					return Object.isNumber(expression) ? Element.descendants(element)[expression] : Element.select(element, expression)[index || 0];
				},
				previous : function(element, expression, index) {
					element = $(element);
					if(arguments.length == 1)
						return $(Selector.handlers.previousElementSibling(element));
					var previousSiblings = Element.previousSiblings(element);
					return Object.isNumber(expression) ? previousSiblings[expression] : Selector.findElement(previousSiblings, expression, index);
				},
				next : function(element, expression, index) {
					element = $(element);
					if(arguments.length == 1)
						return $(Selector.handlers.nextElementSibling(element));
					var nextSiblings = Element.nextSiblings(element);
					return Object.isNumber(expression) ? nextSiblings[expression] : Selector.findElement(nextSiblings, expression, index);
				},
				select : function(element) {
					var args = Array.prototype.slice.call(arguments, 1);
					return Selector.findChildElements(element, args);
				},
				adjacent : function(element) {
					var args = Array.prototype.slice.call(arguments, 1);
					return Selector.findChildElements(element.parentNode, args).without(element);
				},
				identify : function(element) {
					element = $(element);
					var id = Element.readAttribute(element, 'id');
					if(id)
						return id;
					do {
						id = 'anonymous_element_' + Element.idCounter++
					} while ($(id));
					Element.writeAttribute(element, 'id', id);
					return id;
				},
				readAttribute : function(element, name) {
					element = $(element);
					if(Prototype.Browser.IE) {
						var t = Element._attributeTranslations.read;
						if(t.values[name])
							return t.values[name](element, name);
						if(t.names[name])
							name = t.names[name];
						if(name.include(':')) {
							return (!element.attributes || !element.attributes[name]) ? null : element.attributes[name].value;
						}
					}
					return element.getAttribute(name);
				},
				writeAttribute : function(element, name, value) {
					element = $(element);
					var attributes = { }, t = Element._attributeTranslations.write;

					if( typeof name == 'object')
						attributes = name;
					else
						attributes[name] = Object.isUndefined(value) ? true : value;

					for(var attr in attributes) {
						name = t.names[attr] || attr;
						value = attributes[attr];
						if(t.values[attr])
							name = t.values[attr](element, value);
						if(value === false || value === null)
							element.removeAttribute(name);
						else if(value === true)
							element.setAttribute(name, name);
						else
							element.setAttribute(name, value);
					}
					return element;
				},
				getHeight : function(element) {
					return Element.getDimensions(element).height;
				},
				getWidth : function(element) {
					return Element.getDimensions(element).width;
				},
				classNames : function(element) {
					return new Element.ClassNames(element);
				},
				hasClassName : function(element, className) {
					if(!( element = $(element)))
						return;
					var elementClassName = element.className;
					return (elementClassName.length > 0 && (elementClassName == className || new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
				},
				addClassName : function(element, className) {
					if(!( element = $(element)))
						return;
					if(!Element.hasClassName(element, className))
						element.className += (element.className ? ' ' : '') + className;
					return element;
				},
				removeClassName : function(element, className) {
					if(!( element = $(element)))
						return;
					element.className = element.className.replace(new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();
					return element;
				},
				toggleClassName : function(element, className) {
					if(!( element = $(element)))
						return;
					return Element[Element.hasClassName(element, className) ?
					'removeClassName' : 'addClassName'](element, className);
				},
				cleanWhitespace : function(element) {
					element = $(element);
					var node = element.firstChild;
					while(node) {
						var nextNode = node.nextSibling;
						if(node.nodeType == 3 && !/\S/.test(node.nodeValue))
							element.removeChild(node);
						node = nextNode;
					}
					return element;
				},
				empty : function(element) {
					return $(element).innerHTML.blank();
				},
				descendantOf : function(element, ancestor) { element = $(element), ancestor = $(ancestor);

					if(element.compareDocumentPosition)
						return (element.compareDocumentPosition(ancestor) & 8) === 8;

					if(ancestor.contains)
						return ancestor.contains(element) && ancestor !== element;

					while( element = element.parentNode)
					if(element == ancestor)
						return true;

					return false;
				},
				scrollTo : function(element) {
					element = $(element);
					var pos = Element.cumulativeOffset(element);
					window.scrollTo(pos[0], pos[1]);
					return element;
				},
				getStyle : function(element, style) {
					element = $(element);
					style = style == 'float' ? 'cssFloat' : style.camelize();
					var value = element.style[style];
					if(!value || value == 'auto') {
						var css = document.defaultView.getComputedStyle(element, null);
						value = css ? css[style] : null;
					}
					if(style == 'opacity')
						return value ? parseFloat(value) : 1.0;
					return value == 'auto' ? null : value;
				},
				getOpacity : function(element) {
					return $(element).getStyle('opacity');
				},
				setStyle : function(element, styles) {
					element = $(element);
					var elementStyle = element.style, match;
					if(Object.isString(styles)) {
						element.style.cssText += ';' + styles;
						return styles.include('opacity') ? element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
					}
					for(var property in styles)
					if(property == 'opacity')
						element.setOpacity(styles[property]);
					else
						elementStyle[(property == 'float' || property == 'cssFloat') ? (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') : property] = styles[property];

					return element;
				},
				setOpacity : function(element, value) {
					element = $(element);
					element.style.opacity = (value == 1 || value === '') ? '' : (value < 0.00001) ? 0 : value;
					return element;
				},
				getDimensions : function(element) {
					element = $(element);
					var display = Element.getStyle(element, 'display');
					if(display != 'none' && display != null)// Safari bug
						return {
							width : element.offsetWidth,
							height : element.offsetHeight
						};

					var els = element.style;
					var originalVisibility = els.visibility;
					var originalPosition = els.position;
					var originalDisplay = els.display;
					els.visibility = 'hidden';
					if(originalPosition != 'fixed')// Switching fixed to absolute causes issues in Safari
						els.position = 'absolute';
					els.display = 'block';
					var originalWidth = element.clientWidth;
					var originalHeight = element.clientHeight;
					els.display = originalDisplay;
					els.position = originalPosition;
					els.visibility = originalVisibility;
					return {
						width : originalWidth,
						height : originalHeight
					};
				},
				makePositioned : function(element) {
					element = $(element);
					var pos = Element.getStyle(element, 'position');
					if(pos == 'static' || !pos) {
						element._madePositioned = true;
						element.style.position = 'relative';
						if(Prototype.Browser.Opera) {
							element.style.top = 0;
							element.style.left = 0;
						}
					}
					return element;
				},
				undoPositioned : function(element) {
					element = $(element);
					if(element._madePositioned) {
						element._madePositioned = undefined;
						element.style.position = element.style.top = element.style.left = element.style.bottom = element.style.right = '';
					}
					return element;
				},
				makeClipping : function(element) {
					element = $(element);
					if(element._overflow)
						return element;
					element._overflow = Element.getStyle(element, 'overflow') || 'auto';
					if(element._overflow !== 'hidden')
						element.style.overflow = 'hidden';
					return element;
				},
				undoClipping : function(element) {
					element = $(element);
					if(!element._overflow)
						return element;
					element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
					element._overflow = null;
					return element;
				},
				cumulativeOffset : function(element) {
					var valueT = 0, valueL = 0;
					do {
						valueT += element.offsetTop || 0;
						valueL += element.offsetLeft || 0;
						element = element.offsetParent;
					} while (element);
					return Element._returnOffset(valueL, valueT);
				},
				positionedOffset : function(element) {
					var valueT = 0, valueL = 0;
					do {
						valueT += element.offsetTop || 0;
						valueL += element.offsetLeft || 0;
						element = element.offsetParent;
						if(element) {
							if(element.tagName.toUpperCase() == 'BODY')
								break;
							var p = Element.getStyle(element, 'position');
							if(p !== 'static')
								break;
						}
					} while (element);
					return Element._returnOffset(valueL, valueT);
				},
				absolutize : function(element) {
					element = $(element);
					if(Element.getStyle(element, 'position') == 'absolute')
						return element;

					var offsets = Element.positionedOffset(element);
					var top = offsets[1];
					var left = offsets[0];
					var width = element.clientWidth;
					var height = element.clientHeight;

					element._originalLeft = left - parseFloat(element.style.left || 0);
					element._originalTop = top - parseFloat(element.style.top || 0);
					element._originalWidth = element.style.width;
					element._originalHeight = element.style.height;

					element.style.position = 'absolute';
					element.style.top = top + 'px';
					element.style.left = left + 'px';
					element.style.width = width + 'px';
					element.style.height = height + 'px';
					return element;
				},
				relativize : function(element) {
					element = $(element);
					if(Element.getStyle(element, 'position') == 'relative')
						return element;

					element.style.position = 'relative';
					var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
					var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);

					element.style.top = top + 'px';
					element.style.left = left + 'px';
					element.style.height = element._originalHeight;
					element.style.width = element._originalWidth;
					return element;
				},
				cumulativeScrollOffset : function(element) {
					var valueT = 0, valueL = 0;
					do {
						valueT += element.scrollTop || 0;
						valueL += element.scrollLeft || 0;
						element = element.parentNode;
					} while (element);
					return Element._returnOffset(valueL, valueT);
				},
				getOffsetParent : function(element) {
					if(element.offsetParent)
						return $(element.offsetParent);
					if(element == document.body)
						return $(element);

					while(( element = element.parentNode) && element != document.body)
					if(Element.getStyle(element, 'position') != 'static')
						return $(element);

					return $(document.body);
				},
				viewportOffset : function(forElement) {
					var valueT = 0, valueL = 0;

					var element = forElement;
					do {
						valueT += element.offsetTop || 0;
						valueL += element.offsetLeft || 0;

						if(element.offsetParent == document.body && Element.getStyle(element, 'position') == 'absolute')
							break;

					} while (element = element.offsetParent);
					element = forElement;
					do {
						if(!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) {
							valueT -= element.scrollTop || 0;
							valueL -= element.scrollLeft || 0;
						}
					} while (element = element.parentNode);

					return Element._returnOffset(valueL, valueT);
				},
				clonePosition : function(element, source) {
					var options = Object.extend({
						setLeft : true,
						setTop : true,
						setWidth : true,
						setHeight : true,
						offsetTop : 0,
						offsetLeft : 0
					}, arguments[2] || { });
					source = $(source);
					var p = Element.viewportOffset(source);
					element = $(element);
					var delta = [0, 0];
					var parent = null;
					if(Element.getStyle(element, 'position') == 'absolute') {
						parent = Element.getOffsetParent(element);
						delta = Element.viewportOffset(parent);
					}

					if(parent == document.body) {
						delta[0] -= document.body.offsetLeft;
						delta[1] -= document.body.offsetTop;
					}

					if(options.setLeft)
						element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
					if(options.setTop)
						element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
					if(options.setWidth)
						element.style.width = source.offsetWidth + 'px';
					if(options.setHeight)
						element.style.height = source.offsetHeight + 'px';
					return element;
				}
			};

			Object.extend(Element.Methods, {
				getElementsBySelector : Element.Methods.select,

				childElements : Element.Methods.immediateDescendants
			});

			Element._attributeTranslations = {
				write : {
					names : {
						className : 'class',
						htmlFor : 'for'
					},
					values : { }
				}
			};

			if(Prototype.Browser.Opera) {
				Element.Methods.getStyle = Element.Methods.getStyle.wrap(function(proceed, element, style) {
					switch (style) {
						case 'left':
						case 'top':
						case 'right':
						case 'bottom':
							if(proceed(element, 'position') === 'static')
								return null;
						case 'height':
						case 'width':
							if(!Element.visible(element))
								return null;

							var dim = parseInt(proceed(element, style), 10);

							if(dim !== element['offset' + style.capitalize()])
								return dim + 'px';

							var properties;
							if(style === 'height') {
								properties = ['border-top-width', 'padding-top', 'padding-bottom', 'border-bottom-width'];
							} else {
								properties = ['border-left-width', 'padding-left', 'padding-right', 'border-right-width'];
							}
							return properties.inject(dim, function(memo, property) {
								var val = proceed(element, property);
								return val === null ? memo : memo - parseInt(val, 10);
							}) + 'px';
						default:
							return proceed(element, style);
					}
				});

				Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(function(proceed, element, attribute) {
					if(attribute === 'title')
						return element.title;
					return proceed(element, attribute);
				});
			} else if(Prototype.Browser.IE) {
				Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(function(proceed, element) {
					element = $(element);
					try {
						element.offsetParent
					} catch(e) {
						return $(document.body)
					}
					var position = element.getStyle('position');
					if(position !== 'static')
						return proceed(element);
					element.setStyle({
						position : 'relative'
					});
					var value = proceed(element);
					element.setStyle({
						position : position
					});
					return value;
				});

				$w('positionedOffset viewportOffset').each(function(method) {
					Element.Methods[method] = Element.Methods[method].wrap(function(proceed, element) {
						element = $(element);
						try {
							element.offsetParent
						} catch(e) {
							return Element._returnOffset(0, 0)
						}
						var position = element.getStyle('position');
						if(position !== 'static')
							return proceed(element);
						var offsetParent = element.getOffsetParent();
						if(offsetParent && offsetParent.getStyle('position') === 'fixed')
							offsetParent.setStyle({
								zoom : 1
							});
						element.setStyle({
							position : 'relative'
						});
						var value = proceed(element);
						element.setStyle({
							position : position
						});
						return value;
					});
				});

				Element.Methods.cumulativeOffset = Element.Methods.cumulativeOffset.wrap(function(proceed, element) {
					try {
						element.offsetParent
					} catch(e) {
						return Element._returnOffset(0, 0)
					}
					return proceed(element);
				});

				Element.Methods.getStyle = function(element, style) {
					element = $(element);
					style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
					var value = element.style[style];
					if(!value && element.currentStyle)
						value = element.currentStyle[style];

					if(style == 'opacity') {
						if( value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
							if(value[1])
								return parseFloat(value[1]) / 100;
						return 1.0;
					}

					if(value == 'auto') {
						if((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
							return element['offset' + style.capitalize()] + 'px';
						return null;
					}
					return value;
				};

				Element.Methods.setOpacity = function(element, value) {
					function stripAlpha(filter) {
						return filter.replace(/alpha\([^\)]*\)/gi, '');
					}

					element = $(element);
					var currentStyle = element.currentStyle;
					if((currentStyle && !currentStyle.hasLayout) || (!currentStyle && element.style.zoom == 'normal'))
						element.style.zoom = 1;

					var filter = element.getStyle('filter'), style = element.style;
					if(value == 1 || value === '') {( filter = stripAlpha(filter)) ? style.filter = filter : style.removeAttribute('filter');
						return element;
					} else if(value < 0.00001)
						value = 0;
					style.filter = stripAlpha(filter) + 'alpha(opacity=' + (value * 100) + ')';
					return element;
				};

				Element._attributeTranslations = (function() {

					var classProp = 'className';
					var forProp = 'for';

					var el = document.createElement('div');

					el.setAttribute(classProp, 'x');

					if(el.className !== 'x') {
						el.setAttribute('class', 'x');
						if(el.className === 'x') {
							classProp = 'class';
						}
					}
					el = null;
					el = document.createElement('label');
					el.setAttribute(forProp, 'x');
					if(el.htmlFor !== 'x') {
						el.setAttribute('htmlFor', 'x');
						if(el.htmlFor === 'x') {
							forProp = 'htmlFor';
						}
					}
					el = null;

					return {
						read : {
							names : {
								'class' : classProp,
								'className' : classProp,
								'for' : forProp,
								'htmlFor' : forProp
							},
							values : {
								_getAttr : function(element, attribute) {
									return element.getAttribute(attribute);
								},
								_getAttr2 : function(element, attribute) {
									return element.getAttribute(attribute, 2);
								},
								_getAttrNode : function(element, attribute) {
									var node = element.getAttributeNode(attribute);
									return node ? node.value : "";
								},
								_getEv : (function() {

									var el = document.createElement('div');
									el.onclick = Prototype.emptyFunction;
									var value = el.getAttribute('onclick');
									var f;

									if(String(value).indexOf('{') > -1) {
										f = function(element, attribute) {
											attribute = element.getAttribute(attribute);
											if(!attribute)
												return null;
											attribute = attribute.toString();
											attribute = attribute.split('{')[1];
											attribute = attribute.split('}')[0];
											return attribute.strip();
										};
									} else if(value === '') {
										f = function(element, attribute) {
											attribute = element.getAttribute(attribute);
											if(!attribute)
												return null;
											return attribute.strip();
										};
									}
									el = null;
									return f;
								})(),
								_flag : function(element, attribute) {
									return $(element).hasAttribute(attribute) ? attribute : null;
								},
								style : function(element) {
									return element.style.cssText.toLowerCase();
								},
								title : function(element) {
									return element.title;
								}
							}
						}
					}
				})();

				Element._attributeTranslations.write = {
					names : Object.extend({
						cellpadding : 'cellPadding',
						cellspacing : 'cellSpacing'
					}, Element._attributeTranslations.read.names),
					values : {
						checked : function(element, value) {
							element.checked = !!value;
						},
						style : function(element, value) {
							element.style.cssText = value ? value : '';
						}
					}
				};

				Element._attributeTranslations.has = {};

				$w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' + 'encType maxLength readOnly longDesc frameBorder').each(function(attr) {
					Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
					Element._attributeTranslations.has[attr.toLowerCase()] = attr;
				}); (function(v) {
					Object.extend(v, {
						href : v._getAttr2,
						src : v._getAttr2,
						type : v._getAttr,
						action : v._getAttrNode,
						disabled : v._flag,
						checked : v._flag,
						readonly : v._flag,
						multiple : v._flag,
						onload : v._getEv,
						onunload : v._getEv,
						onclick : v._getEv,
						ondblclick : v._getEv,
						onmousedown : v._getEv,
						onmouseup : v._getEv,
						onmouseover : v._getEv,
						onmousemove : v._getEv,
						onmouseout : v._getEv,
						onfocus : v._getEv,
						onblur : v._getEv,
						onkeypress : v._getEv,
						onkeydown : v._getEv,
						onkeyup : v._getEv,
						onsubmit : v._getEv,
						onreset : v._getEv,
						onselect : v._getEv,
						onchange : v._getEv
					});
				})(Element._attributeTranslations.read.values);

				if(Prototype.BrowserFeatures.ElementExtensions) {(function() {
						function _descendants(element) {
							var nodes = element.getElementsByTagName('*'), results = [];
							for(var i = 0, node; node = nodes[i]; i++)
							if(node.tagName !== "!")// Filter out comment nodes.
								results.push(node);
							return results;
						}


						Element.Methods.down = function(element, expression, index) {
							element = $(element);
							if(arguments.length == 1)
								return element.firstDescendant();
							return Object.isNumber(expression) ? _descendants(element)[expression] : Element.select(element, expression)[index || 0];
						}
					})();
				}

			} else if(Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
				Element.Methods.setOpacity = function(element, value) {
					element = $(element);
					element.style.opacity = (value == 1) ? 0.999999 : (value === '') ? '' : (value < 0.00001) ? 0 : value;
					return element;
				};
			} else if(Prototype.Browser.WebKit) {
				Element.Methods.setOpacity = function(element, value) {
					element = $(element);
					element.style.opacity = (value == 1 || value === '') ? '' : (value < 0.00001) ? 0 : value;

					if(value == 1)
						if(element.tagName.toUpperCase() == 'IMG' && element.width) {
							element.width++;
							element.width--;
						} else
							try {
								var n = document.createTextNode(' ');
								element.appendChild(n);
								element.removeChild(n);
							} catch (e) {
							}

					return element;
				};

				Element.Methods.cumulativeOffset = function(element) {
					var valueT = 0, valueL = 0;
					do {
						valueT += element.offsetTop || 0;
						valueL += element.offsetLeft || 0;
						if(element.offsetParent == document.body)
							if(Element.getStyle(element, 'position') == 'absolute')
								break;
						element = element.offsetParent;
					} while (element);

					return Element._returnOffset(valueL, valueT);
				};
			}

			if('outerHTML' in document.documentElement) {
				Element.Methods.replace = function(element, content) {
					element = $(element);

					if(content && content.toElement)
						content = content.toElement();
					if(Object.isElement(content)) {
						element.parentNode.replaceChild(content, element);
						return element;
					}
					content = Object.toHTML(content);
					var parent = element.parentNode, tagName = parent.tagName.toUpperCase();

					if(Element._insertionTranslations.tags[tagName]) {
						var nextSibling = element.next();
						var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
						parent.removeChild(element);
						if(nextSibling)
							fragments.each(function(node) {
								parent.insertBefore(node, nextSibling)
							});
						else
							fragments.each(function(node) {
								parent.appendChild(node)
							});
					} else
						element.outerHTML = content.stripScripts();

					content.evalScripts.bind(content).defer();
					return element;
				};
			}

			Element._returnOffset = function(l, t) {
				var result = [l, t];
				result.left = l;
				result.top = t;
				return result;
			};

			Element._getContentFromAnonymousElement = function(tagName, html) {
				var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
				if(t) {
					div.innerHTML = t[0] + html + t[1];
					t[2].times(function() {
						div = div.firstChild
					});
				} else
					div.innerHTML = html;
				return $A(div.childNodes);
			};

			Element._insertionTranslations = {
				before : function(element, node) {
					element.parentNode.insertBefore(node, element);
				},
				top : function(element, node) {
					element.insertBefore(node, element.firstChild);
				},
				bottom : function(element, node) {
					element.appendChild(node);
				},
				after : function(element, node) {
					element.parentNode.insertBefore(node, element.nextSibling);
				},
				tags : {
					TABLE : ['<table>', '</table>', 1],
					TBODY : ['<table><tbody>', '</tbody></table>', 2],
					TR : ['<table><tbody><tr>', '</tr></tbody></table>', 3],
					TD : ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
					SELECT : ['<select>', '</select>', 1]
				}
			}; (function() {
				var tags = Element._insertionTranslations.tags;
				Object.extend(tags, {
					THEAD : tags.TBODY,
					TFOOT : tags.TBODY,
					TH : tags.TD
				});
			})();

			Element.Methods.Simulated = {
				hasAttribute : function(element, attribute) {
					attribute = Element._attributeTranslations.has[attribute] || attribute;
					var node = $(element).getAttributeNode(attribute);
					return !!(node && node.specified);
				}
			};

			Element.Methods.ByTag = { };

			Object.extend(Element, Element.Methods); (function(div) {

				if(!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) {
					window.HTMLElement = { };
					window.HTMLElement.prototype = div['__proto__'];
					Prototype.BrowserFeatures.ElementExtensions = true;
				}
				div = null;

			})(document.createElement('div'))

			Element.extend = (function() {

				function checkDeficiency(tagName) {
					if( typeof window.Element != 'undefined') {
						var proto = window.Element.prototype;
						if(proto) {
							var id = '_' + (Math.random() + '').slice(2);
							var el = document.createElement(tagName);
							proto[id] = 'x';
							var isBuggy = (el[id] !== 'x');
							delete proto[id];
							el = null;
							return isBuggy;
						}
					}
					return false;
				}

				function extendElementWith(element, methods) {
					for(var property in methods) {
						var value = methods[property];
						if(Object.isFunction(value) && !( property in element))
							element[property] = value.methodize();
					}
				}

				var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object');

				if(Prototype.BrowserFeatures.SpecificElementExtensions) {
					if(HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) {
						return function(element) {
							if(element && typeof element._extendedByPrototype == 'undefined') {
								var t = element.tagName;
								if(t && (/^(?:object|applet|embed)$/i.test(t))) {
									extendElementWith(element, Element.Methods);
									extendElementWith(element, Element.Methods.Simulated);
									extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]);
								}
							}
							return element;
						}
					}
					return Prototype.K;
				}

				var Methods = { }, ByTag = Element.Methods.ByTag;

				var extend = Object.extend(function(element) {
					if(!element || typeof element._extendedByPrototype != 'undefined' || element.nodeType != 1 || element == window)
						return element;

					var methods = Object.clone(Methods), tagName = element.tagName.toUpperCase();

					if(ByTag[tagName])
						Object.extend(methods, ByTag[tagName]);

					extendElementWith(element, methods);

					element._extendedByPrototype = Prototype.emptyFunction;
					return element;

				}, {
					refresh : function() {
						if(!Prototype.BrowserFeatures.ElementExtensions) {
							Object.extend(Methods, Element.Methods);
							Object.extend(Methods, Element.Methods.Simulated);
						}
					}
				});

				extend.refresh();
				return extend;
			})();

			Element.hasAttribute = function(element, attribute) {
				if(element.hasAttribute)
					return element.hasAttribute(attribute);
				return Element.Methods.Simulated.hasAttribute(element, attribute);
			};

			Element.addMethods = function(methods) {
				var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;

				if(!methods) {
					Object.extend(Form, Form.Methods);
					Object.extend(Form.Element, Form.Element.Methods);
					Object.extend(Element.Methods.ByTag, {
						"FORM" : Object.clone(Form.Methods),
						"INPUT" : Object.clone(Form.Element.Methods),
						"SELECT" : Object.clone(Form.Element.Methods),
						"TEXTAREA" : Object.clone(Form.Element.Methods)
					});
				}

				if(arguments.length == 2) {
					var tagName = methods;
					methods = arguments[1];
				}

				if(!tagName)
					Object.extend(Element.Methods, methods || { });
				else {
					if(Object.isArray(tagName))
						tagName.each(extend);
					else
						extend(tagName);
				}

				function extend(tagName) {
					tagName = tagName.toUpperCase();
					if(!Element.Methods.ByTag[tagName])
						Element.Methods.ByTag[tagName] = { };
					Object.extend(Element.Methods.ByTag[tagName], methods);
				}

				function copy(methods, destination, onlyIfAbsent) {
					onlyIfAbsent = onlyIfAbsent || false;
					for(var property in methods) {
						var value = methods[property];
						if(!Object.isFunction(value))
							continue;
						if(!onlyIfAbsent || !( property in destination))
							destination[property] = value.methodize();
					}
				}

				function findDOMClass(tagName) {
					var klass;
					var trans = {
						"OPTGROUP" : "OptGroup",
						"TEXTAREA" : "TextArea",
						"P" : "Paragraph",
						"FIELDSET" : "FieldSet",
						"UL" : "UList",
						"OL" : "OList",
						"DL" : "DList",
						"DIR" : "Directory",
						"H1" : "Heading",
						"H2" : "Heading",
						"H3" : "Heading",
						"H4" : "Heading",
						"H5" : "Heading",
						"H6" : "Heading",
						"Q" : "Quote",
						"INS" : "Mod",
						"DEL" : "Mod",
						"A" : "Anchor",
						"IMG" : "Image",
						"CAPTION" : "TableCaption",
						"COL" : "TableCol",
						"COLGROUP" : "TableCol",
						"THEAD" : "TableSection",
						"TFOOT" : "TableSection",
						"TBODY" : "TableSection",
						"TR" : "TableRow",
						"TH" : "TableCell",
						"TD" : "TableCell",
						"FRAMESET" : "FrameSet",
						"IFRAME" : "IFrame"
					};
					if(trans[tagName])
						klass = 'HTML' + trans[tagName] + 'Element';
					if(window[klass])
						return window[klass];
					klass = 'HTML' + tagName + 'Element';
					if(window[klass])
						return window[klass];
					klass = 'HTML' + tagName.capitalize() + 'Element';
					if(window[klass])
						return window[klass];

					var element = document.createElement(tagName);
					var proto = element['__proto__'] || element.constructor.prototype;
					element = null;
					return proto;
				}

				var elementPrototype = window.HTMLElement ? HTMLElement.prototype : Element.prototype;

				if(F.ElementExtensions) {
					copy(Element.Methods, elementPrototype);
					copy(Element.Methods.Simulated, elementPrototype, true);
				}

				if(F.SpecificElementExtensions) {
					for(var tag in Element.Methods.ByTag) {
						var klass = findDOMClass(tag);
						if(Object.isUndefined(klass))
							continue;
						copy(T[tag], klass.prototype);
					}
				}

				Object.extend(Element, Element.Methods);
				delete Element.ByTag;

				if(Element.extend.refresh)
					Element.extend.refresh();
				Element.cache = { };
			};

			document.viewport = {

				getDimensions : function() {
					return {
						width : this.getWidth(),
						height : this.getHeight()
					};
				},
				getScrollOffsets : function() {
					return Element._returnOffset(window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft, window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
				}
			}; (function(viewport) {
				var B = Prototype.Browser, doc = document, element, property = {};

				function getRootElement() {
					if(B.WebKit && !doc.evaluate)
						return document;

					if(B.Opera && window.parseFloat(window.opera.version()) < 9.5)
						return document.body;

					return document.documentElement;
				}

				function define(D) {
					if(!element)
						element = getRootElement();

					property[D] = 'client' + D;

					viewport['get' + D] = function() {
						return element[property[D]]
					};
					return viewport['get' + D]();
				}


				viewport.getWidth = define.curry('Width');

				viewport.getHeight = define.curry('Height');
			})(document.viewport);

			Element.Storage = {
				UID : 1
			};

			Element.addMethods({
				getStorage : function(element) {
					if(!( element = $(element)))
						return;

					var uid;
					if(element === window) {
						uid = 0;
					} else {
						if( typeof element._prototypeUID === "undefined")
							element._prototypeUID = [Element.Storage.UID++];
						uid = element._prototypeUID[0];
					}

					if(!Element.Storage[uid])
						Element.Storage[uid] = $H();

					return Element.Storage[uid];
				},
				store : function(element, key, value) {
					if(!( element = $(element)))
						return;

					if(arguments.length === 2) {
						Element.getStorage(element).update(key);
					} else {
						Element.getStorage(element).set(key, value);
					}

					return element;
				},
				retrieve : function(element, key, defaultValue) {
					if(!( element = $(element)))
						return;
					var hash = Element.getStorage(element), value = hash.get(key);

					if(Object.isUndefined(value)) {
						hash.set(key, defaultValue);
						value = defaultValue;
					}

					return value;
				},
				clone : function(element, deep) {
					if(!( element = $(element)))
						return;
					var clone = element.cloneNode(deep);
					clone._prototypeUID =
					void 0;
					if(deep) {
						var descendants = Element.select(clone, '*'), i = descendants.length;
						while(i--) {
							descendants[i]._prototypeUID =
							void 0;
						}
					}
					return Element.extend(clone);
				}
			});
			/* Portions of the Selector class are derived from Jack Slocum's DomQuery,
			 * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
			 * license.  Please see http://www.yui-ext.com/ for more information. */

			var Selector = Class.create({
				initialize : function(expression) {
					this.expression = expression.strip();

					if(this.shouldUseSelectorsAPI()) {
						this.mode = 'selectorsAPI';
					} else if(this.shouldUseXPath()) {
						this.mode = 'xpath';
						this.compileXPathMatcher();
					} else {
						this.mode = "normal";
						this.compileMatcher();
					}

				},
				shouldUseXPath : (function() {

					var IS_DESCENDANT_SELECTOR_BUGGY = (function() {
						var isBuggy = false;
						if(document.evaluate && window.XPathResult) {
							var el = document.createElement('div');
							el.innerHTML = '<ul><li></li></ul><div><ul><li></li></ul></div>';

							var xpath = ".//*[local-name()='ul' or local-name()='UL']" + "//*[local-name()='li' or local-name()='LI']";

							var result = document.evaluate(xpath, el, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
							isBuggy = (result.snapshotLength !== 2);
							el = null;
						}
						return isBuggy;
					})();

					return function() {
						if(!Prototype.BrowserFeatures.XPath)
							return false;

						var e = this.expression;

						if(Prototype.Browser.WebKit && (e.include("-of-type") || e.include(":empty")))
							return false;

						if((/(\[[\w-]*?:|:checked)/).test(e))
							return false;

						if(IS_DESCENDANT_SELECTOR_BUGGY)
							return false;

						return true;
					}
				})(),

				shouldUseSelectorsAPI : function() {
					if(!Prototype.BrowserFeatures.SelectorsAPI)
						return false;

					if(Selector.CASE_INSENSITIVE_CLASS_NAMES)
						return false;

					if(!Selector._div)
						Selector._div = new Element('div');

					try {
						Selector._div.querySelector(this.expression);
					} catch(e) {
						return false;
					}

					return true;
				},
				compileMatcher : function() {
					var e = this.expression, ps = Selector.patterns, h = Selector.handlers, c = Selector.criteria, le, p, m, len = ps.length, name;

					if(Selector._cache[e]) {
						this.matcher = Selector._cache[e];
						return;
					}

					this.matcher = ["this.matcher = function(root) {", "var r = root, h = Selector.handlers, c = false, n;"];

					while(e && le != e && (/\S/).test(e)) {
						le = e;
						for(var i = 0; i < len; i++) {
							p = ps[i].re;
							name = ps[i].name;
							if( m = e.match(p)) {
								this.matcher.push(Object.isFunction(c[name]) ? c[name](m) : new Template(c[name]).evaluate(m));
								e = e.replace(m[0], '');
								break;
							}
						}
					}

					this.matcher.push("return h.unique(n);\n}");
					eval(this.matcher.join('\n'));
					Selector._cache[this.expression] = this.matcher;
				},
				compileXPathMatcher : function() {
					var e = this.expression, ps = Selector.patterns, x = Selector.xpath, le, m, len = ps.length, name;

					if(Selector._cache[e]) {
						this.xpath = Selector._cache[e];
						return;
					}

					this.matcher = ['.//*'];
					while(e && le != e && (/\S/).test(e)) {
						le = e;
						for(var i = 0; i < len; i++) {
							name = ps[i].name;
							if( m = e.match(ps[i].re)) {
								this.matcher.push(Object.isFunction(x[name]) ? x[name](m) : new Template(x[name]).evaluate(m));
								e = e.replace(m[0], '');
								break;
							}
						}
					}

					this.xpath = this.matcher.join('');
					Selector._cache[this.expression] = this.xpath;
				},
				findElements : function(root) {
					root = root || document;
					var e = this.expression, results;

					switch (this.mode) {
						case 'selectorsAPI':
							if(root !== document) {
								var oldId = root.id, id = $(root).identify();
								id = id.replace(/([\.:])/g, "\\$1");
								e = "#" + id + " " + e;
							}
							results = $A(root.querySelectorAll(e)).map(Element.extend);
							root.id = oldId;

							return results;
						case 'xpath':
							return document._getElementsByXPath(this.xpath, root);
						default:
							return this.matcher(root);
					}
				},
				match : function(element) {
					this.tokens = [];

					var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
					var le, p, m, len = ps.length, name;

					while(e && le !== e && (/\S/).test(e)) {
						le = e;
						for(var i = 0; i < len; i++) {
							p = ps[i].re;
							name = ps[i].name;
							if( m = e.match(p)) {
								if(as[name]) {
									this.tokens.push([name, Object.clone(m)]);
									e = e.replace(m[0], '');
								} else {
									return this.findElements(document).include(element);
								}
							}
						}
					}

					var match = true, name, matches;
					for(var i = 0, token; token = this.tokens[i]; i++) { name = token[0], matches = token[1];
						if(!Selector.assertions[name](element, matches)) {
							match = false;
							break;
						}
					}

					return match;
				},
				toString : function() {
					return this.expression;
				},
				inspect : function() {
					return "#<Selector:" + this.expression.inspect() + ">";
				}
			});

			if(Prototype.BrowserFeatures.SelectorsAPI && document.compatMode === 'BackCompat') {
				Selector.CASE_INSENSITIVE_CLASS_NAMES = (function() {
					var div = document.createElement('div'), span = document.createElement('span');

					div.id = "prototype_test_id";
					span.className = 'Test';
					div.appendChild(span);
					var isIgnored = (div.querySelector('#prototype_test_id .test') !== null);
					div = span = null;
					return isIgnored;
				})();
			}

			Object.extend(Selector, {
				_cache : { },

				xpath : {
					descendant : "//*",
					child : "/*",
					adjacent : "/following-sibling::*[1]",
					laterSibling : '/following-sibling::*',
					tagName : function(m) {
						if(m[1] == '*')
							return '';
						return "[local-name()='" + m[1].toLowerCase() + "' or local-name()='" + m[1].toUpperCase() + "']";
					},
					className : "[contains(concat(' ', @class, ' '), ' #{1} ')]",
					id : "[@id='#{1}']",
					attrPresence : function(m) {
						m[1] = m[1].toLowerCase();
						return new Template("[@#{1}]").evaluate(m);
					},
					attr : function(m) {
						m[1] = m[1].toLowerCase();
						m[3] = m[5] || m[6];
						return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
					},
					pseudo : function(m) {
						var h = Selector.xpath.pseudos[m[1]];
						if(!h)
							return '';
						if(Object.isFunction(h))
							return h(m);
						return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
					},
					operators : {
						'=' : "[@#{1}='#{3}']",
						'!=' : "[@#{1}!='#{3}']",
						'^=' : "[starts-with(@#{1}, '#{3}')]",
						'$=' : "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
						'*=' : "[contains(@#{1}, '#{3}')]",
						'~=' : "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
						'|=' : "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
					},
					pseudos : {
						'first-child' : '[not(preceding-sibling::*)]',
						'last-child' : '[not(following-sibling::*)]',
						'only-child' : '[not(preceding-sibling::* or following-sibling::*)]',
						'empty' : "[count(*) = 0 and (count(text()) = 0)]",
						'checked' : "[@checked]",
						'disabled' : "[(@disabled) and (@type!='hidden')]",
						'enabled' : "[not(@disabled) and (@type!='hidden')]",
						'not' : function(m) {
							var e = m[6], p = Selector.patterns, x = Selector.xpath, le, v, len = p.length, name;

							var exclusion = [];
							while(e && le != e && (/\S/).test(e)) {
								le = e;
								for(var i = 0; i < len; i++) {
									name = p[i].name
									if( m = e.match(p[i].re)) {
										v = Object.isFunction(x[name]) ? x[name](m) : new Template(x[name]).evaluate(m);
										exclusion.push("(" + v.substring(1, v.length - 1) + ")");
										e = e.replace(m[0], '');
										break;
									}
								}
							}
							return "[not(" + exclusion.join(" and ") + ")]";
						},
						'nth-child' : function(m) {
							return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
						},
						'nth-last-child' : function(m) {
							return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
						},
						'nth-of-type' : function(m) {
							return Selector.xpath.pseudos.nth("position() ", m);
						},
						'nth-last-of-type' : function(m) {
							return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
						},
						'first-of-type' : function(m) {
							m[6] = "1";
							return Selector.xpath.pseudos['nth-of-type'](m);
						},
						'last-of-type' : function(m) {
							m[6] = "1";
							return Selector.xpath.pseudos['nth-last-of-type'](m);
						},
						'only-of-type' : function(m) {
							var p = Selector.xpath.pseudos;
							return p['first-of-type'](m) + p['last-of-type'](m);
						},
						nth : function(fragment, m) {
							var mm, formula = m[6], predicate;
							if(formula == 'even')
								formula = '2n+0';
							if(formula == 'odd')
								formula = '2n+1';
							if( mm = formula.match(/^(\d+)$/))// digit only
								return '[' + fragment + "= " + mm[1] + ']';
							if( mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) {// an+b
								if(mm[1] == "-")
									mm[1] = -1;
								var a = mm[1] ? Number(mm[1]) : 1;
								var b = mm[2] ? Number(mm[2]) : 0;
								predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " + "((#{fragment} - #{b}) div #{a} >= 0)]";
								return new Template(predicate).evaluate({
									fragment : fragment,
									a : a,
									b : b
								});
							}
						}
					}
				},

				criteria : {
					tagName : 'n = h.tagName(n, r, "#{1}", c);      c = false;',
					className : 'n = h.className(n, r, "#{1}", c);    c = false;',
					id : 'n = h.id(n, r, "#{1}", c);           c = false;',
					attrPresence : 'n = h.attrPresence(n, r, "#{1}", c); c = false;',
					attr : function(m) {
						m[3] = (m[5] || m[6]);
						return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m);
					},
					pseudo : function(m) {
						if(m[6])
							m[6] = m[6].replace(/"/g, '\\"');
						return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
					},
					descendant : 'c = "descendant";',
					child : 'c = "child";',
					adjacent : 'c = "adjacent";',
					laterSibling : 'c = "laterSibling";'
				},

				patterns : [{
					name : 'laterSibling',
					re : /^\s*~\s*/
				}, {
					name : 'child',
					re : /^\s*>\s*/
				}, {
					name : 'adjacent',
					re : /^\s*\+\s*/
				}, {
					name : 'descendant',
					re : /^\s/
				}, {
					name : 'tagName',
					re : /^\s*(\*|[\w\-]+)(\b|$)?/
				}, {
					name : 'id',
					re : /^#([\w\-\*]+)(\b|$)/
				}, {
					name : 'className',
					re : /^\.([\w\-\*]+)(\b|$)/
				}, {
					name : 'pseudo',
					re : /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/
				}, {
					name : 'attrPresence',
					re : /^\[((?:[\w-]+:)?[\w-]+)\]/
				}, {
					name : 'attr',
					re : /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
				}],

				assertions : {
					tagName : function(element, matches) {
						return matches[1].toUpperCase() == element.tagName.toUpperCase();
					},
					className : function(element, matches) {
						return Element.hasClassName(element, matches[1]);
					},
					id : function(element, matches) {
						return element.id === matches[1];
					},
					attrPresence : function(element, matches) {
						return Element.hasAttribute(element, matches[1]);
					},
					attr : function(element, matches) {
						var nodeValue = Element.readAttribute(element, matches[1]);
						return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]);
					}
				},

				handlers : {
					concat : function(a, b) {
						for(var i = 0, node; node = b[i]; i++)
						a.push(node);
						return a;
					},
					mark : function(nodes) {
						var _true = Prototype.emptyFunction;
						for(var i = 0, node; node = nodes[i]; i++)
						node._countedByPrototype = _true;
						return nodes;
					},
					unmark : (function() {

						var PROPERTIES_ATTRIBUTES_MAP = (function() {
							var el = document.createElement('div'), isBuggy = false, propName = '_countedByPrototype', value = 'x'
							el[propName] = value;
							isBuggy = (el.getAttribute(propName) === value);
							el = null;
							return isBuggy;
						})();

						return PROPERTIES_ATTRIBUTES_MAP ? function(nodes) {
							for(var i = 0, node; node = nodes[i]; i++)
							node.removeAttribute('_countedByPrototype');
							return nodes;
						} : function(nodes) {
							for(var i = 0, node; node = nodes[i]; i++)
							node._countedByPrototype =
							void 0;
							return nodes;
						}
					})(),

					index : function(parentNode, reverse, ofType) {
						parentNode._countedByPrototype = Prototype.emptyFunction;
						if(reverse) {
							for(var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
								var node = nodes[i];
								if(node.nodeType == 1 && (!ofType || node._countedByPrototype))
									node.nodeIndex = j++;
							}
						} else {
							for(var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
							if(node.nodeType == 1 && (!ofType || node._countedByPrototype))
								node.nodeIndex = j++;
						}
					},
					unique : function(nodes) {
						if(nodes.length == 0)
							return nodes;
						var results = [], n;
						for(var i = 0, l = nodes.length; i < l; i++)
						if( typeof ( n = nodes[i])._countedByPrototype == 'undefined') {
							n._countedByPrototype = Prototype.emptyFunction;
							results.push(Element.extend(n));
						}
						return Selector.handlers.unmark(results);
					},
					descendant : function(nodes) {
						var h = Selector.handlers;
						for(var i = 0, results = [], node; node = nodes[i]; i++)
						h.concat(results, node.getElementsByTagName('*'));
						return results;
					},
					child : function(nodes) {
						var h = Selector.handlers;
						for(var i = 0, results = [], node; node = nodes[i]; i++) {
							for(var j = 0, child; child = node.childNodes[j]; j++)
							if(child.nodeType == 1 && child.tagName != '!')
								results.push(child);
						}
						return results;
					},
					adjacent : function(nodes) {
						for(var i = 0, results = [], node; node = nodes[i]; i++) {
							var next = this.nextElementSibling(node);
							if(next)
								results.push(next);
						}
						return results;
					},
					laterSibling : function(nodes) {
						var h = Selector.handlers;
						for(var i = 0, results = [], node; node = nodes[i]; i++)
						h.concat(results, Element.nextSiblings(node));
						return results;
					},
					nextElementSibling : function(node) {
						while( node = node.nextSibling)
						if(node.nodeType == 1)
							return node;
						return null;
					},
					previousElementSibling : function(node) {
						while( node = node.previousSibling)
						if(node.nodeType == 1)
							return node;
						return null;
					},
					tagName : function(nodes, root, tagName, combinator) {
						var uTagName = tagName.toUpperCase();
						var results = [], h = Selector.handlers;
						if(nodes) {
							if(combinator) {
								if(combinator == "descendant") {
									for(var i = 0, node; node = nodes[i]; i++)
									h.concat(results, node.getElementsByTagName(tagName));
									return results;
								} else
									nodes = this[combinator](nodes);
								if(tagName == "*")
									return nodes;
							}
							for(var i = 0, node; node = nodes[i]; i++)
							if(node.tagName.toUpperCase() === uTagName)
								results.push(node);
							return results;
						} else
							return root.getElementsByTagName(tagName);
					},
					id : function(nodes, root, id, combinator) {
						var targetNode = $(id), h = Selector.handlers;

						if(root == document) {
							if(!targetNode)
								return [];
							if(!nodes)
								return [targetNode];
						} else {
							if(!root.sourceIndex || root.sourceIndex < 1) {
								var nodes = root.getElementsByTagName('*');
								for(var j = 0, node; node = nodes[j]; j++) {
									if(node.id === id)
										return [node];
								}
							}
						}

						if(nodes) {
							if(combinator) {
								if(combinator == 'child') {
									for(var i = 0, node; node = nodes[i]; i++)
									if(targetNode.parentNode == node)
										return [targetNode];
								} else if(combinator == 'descendant') {
									for(var i = 0, node; node = nodes[i]; i++)
									if(Element.descendantOf(targetNode, node))
										return [targetNode];
								} else if(combinator == 'adjacent') {
									for(var i = 0, node; node = nodes[i]; i++)
									if(Selector.handlers.previousElementSibling(targetNode) == node)
										return [targetNode];
								} else
									nodes = h[combinator](nodes);
							}
							for(var i = 0, node; node = nodes[i]; i++)
							if(node == targetNode)
								return [targetNode];
							return [];
						}
						return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
					},
					className : function(nodes, root, className, combinator) {
						if(nodes && combinator)
							nodes = this[combinator](nodes);
						return Selector.handlers.byClassName(nodes, root, className);
					},
					byClassName : function(nodes, root, className) {
						if(!nodes)
							nodes = Selector.handlers.descendant([root]);
						var needle = ' ' + className + ' ';
						for(var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
							nodeClassName = node.className;
							if(nodeClassName.length == 0)
								continue;
							if(nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
								results.push(node);
						}
						return results;
					},
					attrPresence : function(nodes, root, attr, combinator) {
						if(!nodes)
							nodes = root.getElementsByTagName("*");
						if(nodes && combinator)
							nodes = this[combinator](nodes);
						var results = [];
						for(var i = 0, node; node = nodes[i]; i++)
						if(Element.hasAttribute(node, attr))
							results.push(node);
						return results;
					},
					attr : function(nodes, root, attr, value, operator, combinator) {
						if(!nodes)
							nodes = root.getElementsByTagName("*");
						if(nodes && combinator)
							nodes = this[combinator](nodes);
						var handler = Selector.operators[operator], results = [];
						for(var i = 0, node; node = nodes[i]; i++) {
							var nodeValue = Element.readAttribute(node, attr);
							if(nodeValue === null)
								continue;
							if(handler(nodeValue, value))
								results.push(node);
						}
						return results;
					},
					pseudo : function(nodes, name, value, root, combinator) {
						if(nodes && combinator)
							nodes = this[combinator](nodes);
						if(!nodes)
							nodes = root.getElementsByTagName("*");
						return Selector.pseudos[name](nodes, value, root);
					}
				},

				pseudos : {
					'first-child' : function(nodes, value, root) {
						for(var i = 0, results = [], node; node = nodes[i]; i++) {
							if(Selector.handlers.previousElementSibling(node))
								continue;
							results.push(node);
						}
						return results;
					},
					'last-child' : function(nodes, value, root) {
						for(var i = 0, results = [], node; node = nodes[i]; i++) {
							if(Selector.handlers.nextElementSibling(node))
								continue;
							results.push(node);
						}
						return results;
					},
					'only-child' : function(nodes, value, root) {
						var h = Selector.handlers;
						for(var i = 0, results = [], node; node = nodes[i]; i++)
						if(!h.previousElementSibling(node) && !h.nextElementSibling(node))
							results.push(node);
						return results;
					},
					'nth-child' : function(nodes, formula, root) {
						return Selector.pseudos.nth(nodes, formula, root);
					},
					'nth-last-child' : function(nodes, formula, root) {
						return Selector.pseudos.nth(nodes, formula, root, true);
					},
					'nth-of-type' : function(nodes, formula, root) {
						return Selector.pseudos.nth(nodes, formula, root, false, true);
					},
					'nth-last-of-type' : function(nodes, formula, root) {
						return Selector.pseudos.nth(nodes, formula, root, true, true);
					},
					'first-of-type' : function(nodes, formula, root) {
						return Selector.pseudos.nth(nodes, "1", root, false, true);
					},
					'last-of-type' : function(nodes, formula, root) {
						return Selector.pseudos.nth(nodes, "1", root, true, true);
					},
					'only-of-type' : function(nodes, formula, root) {
						var p = Selector.pseudos;
						return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
					},
					getIndices : function(a, b, total) {
						if(a == 0)
							return b > 0 ? [b] : [];
						return $R(1, total).inject([], function(memo, i) {
							if(0 == (i - b) % a && (i - b) / a >= 0)
								memo.push(i);
							return memo;
						});
					},
					nth : function(nodes, formula, root, reverse, ofType) {
						if(nodes.length == 0)
							return [];
						if(formula == 'even')
							formula = '2n+0';
						if(formula == 'odd')
							formula = '2n+1';
						var h = Selector.handlers, results = [], indexed = [], m;
						h.mark(nodes);
						for(var i = 0, node; node = nodes[i]; i++) {
							if(!node.parentNode._countedByPrototype) {
								h.index(node.parentNode, reverse, ofType);
								indexed.push(node.parentNode);
							}
						}
						if(formula.match(/^\d+$/)) {// just a number
							formula = Number(formula);
							for(var i = 0, node; node = nodes[i]; i++)
							if(node.nodeIndex == formula)
								results.push(node);
						} else if( m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) {// an+b
							if(m[1] == "-")
								m[1] = -1;
							var a = m[1] ? Number(m[1]) : 1;
							var b = m[2] ? Number(m[2]) : 0;
							var indices = Selector.pseudos.getIndices(a, b, nodes.length);
							for(var i = 0, node, l = indices.length; node = nodes[i]; i++) {
								for(var j = 0; j < l; j++)
								if(node.nodeIndex == indices[j])
									results.push(node);
							}
						}
						h.unmark(nodes);
						h.unmark(indexed);
						return results;
					},
					'empty' : function(nodes, value, root) {
						for(var i = 0, results = [], node; node = nodes[i]; i++) {
							if(node.tagName == '!' || node.firstChild)
								continue;
							results.push(node);
						}
						return results;
					},
					'not' : function(nodes, selector, root) {
						var h = Selector.handlers, selectorType, m;
						var exclusions = new Selector(selector).findElements(root);
						h.mark(exclusions);
						for(var i = 0, results = [], node; node = nodes[i]; i++)
						if(!node._countedByPrototype)
							results.push(node);
						h.unmark(exclusions);
						return results;
					},
					'enabled' : function(nodes, value, root) {
						for(var i = 0, results = [], node; node = nodes[i]; i++)
						if(!node.disabled && (!node.type || node.type !== 'hidden'))
							results.push(node);
						return results;
					},
					'disabled' : function(nodes, value, root) {
						for(var i = 0, results = [], node; node = nodes[i]; i++)
						if(node.disabled)
							results.push(node);
						return results;
					},
					'checked' : function(nodes, value, root) {
						for(var i = 0, results = [], node; node = nodes[i]; i++)
						if(node.checked)
							results.push(node);
						return results;
					}
				},

				operators : {
					'=' : function(nv, v) {
						return nv == v;
					},
					'!=' : function(nv, v) {
						return nv != v;
					},
					'^=' : function(nv, v) {
						return nv == v || nv && nv.startsWith(v);
					},
					'$=' : function(nv, v) {
						return nv == v || nv && nv.endsWith(v);
					},
					'*=' : function(nv, v) {
						return nv == v || nv && nv.include(v);
					},
					'~=' : function(nv, v) {
						return (' ' + nv + ' ').include(' ' + v + ' ');
					},
					'|=' : function(nv, v) {
						return ('-' + (nv || "").toUpperCase() + '-').include('-' + (v || "").toUpperCase() + '-');
					}
				},

				split : function(expression) {
					var expressions = [];
					expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
						expressions.push(m[1].strip());
					});
					return expressions;
				},
				matchElements : function(elements, expression) {
					var matches = $$(expression), h = Selector.handlers;
					h.mark(matches);
					for(var i = 0, results = [], element; element = elements[i]; i++)
					if(element._countedByPrototype)
						results.push(element);
					h.unmark(matches);
					return results;
				},
				findElement : function(elements, expression, index) {
					if(Object.isNumber(expression)) {
						index = expression;
						expression = false;
					}
					return Selector.matchElements(elements, expression || '*')[index || 0];
				},
				findChildElements : function(element, expressions) {
					expressions = Selector.split(expressions.join(','));
					var results = [], h = Selector.handlers;
					for(var i = 0, l = expressions.length, selector; i < l; i++) {
						selector = new Selector(expressions[i].strip());
						h.concat(results, selector.findElements(element));
					}
					return (l > 1) ? h.unique(results) : results;
				}
			});

			if(Prototype.Browser.IE) {
				Object.extend(Selector.handlers, {
					concat : function(a, b) {
						for(var i = 0, node; node = b[i]; i++)
						if(node.tagName !== "!")
							a.push(node);
						return a;
					}
				});
			}

			function $$() {
				return Selector.findChildElements(document, $A(arguments));
			}

			var Form = {
				reset : function(form) {
					form = $(form);
					form.reset();
					return form;
				},
				serializeElements : function(elements, options) {
					if( typeof options != 'object')
						options = {
							hash : !!options
						};
					else if(Object.isUndefined(options.hash))
						options.hash = true;
					var key, value, submitted = false, submit = options.submit;

					var data = elements.inject({ }, function(result, element) {
						if(!element.disabled && element.name) {
							key = element.name;
							value = $(element).getValue();
							if(value != null && element.type != 'file' && (element.type != 'submit' || (!submitted && submit !== false && (!submit || key == submit) && ( submitted = true)))) {
								if( key in result) {
									if(!Object.isArray(result[key]))
										result[key] = [result[key]];
									result[key].push(value);
								} else
									result[key] = value;
							}
						}
						return result;
					});
					return options.hash ? data : Object.toQueryString(data);
				}
			};

			Form.Methods = {
				serialize : function(form, options) {
					return Form.serializeElements(Form.getElements(form), options);
				},
				getElements : function(form) {
					var elements = $(form).getElementsByTagName('*'), element, arr = [], serializers = Form.Element.Serializers;
					for(var i = 0; element = elements[i]; i++) {
						arr.push(element);
					}
					return arr.inject([], function(elements, child) {
						if(serializers[child.tagName.toLowerCase()])
							elements.push(Element.extend(child));
						return elements;
					})
				},
				getInputs : function(form, typeName, name) {
					form = $(form);
					var inputs = form.getElementsByTagName('input');

					if(!typeName && !name)
						return $A(inputs).map(Element.extend);

					for(var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
						var input = inputs[i];
						if((typeName && input.type != typeName) || (name && input.name != name))
							continue;
						matchingInputs.push(Element.extend(input));
					}

					return matchingInputs;
				},
				disable : function(form) {
					form = $(form);
					Form.getElements(form).invoke('disable');
					return form;
				},
				enable : function(form) {
					form = $(form);
					Form.getElements(form).invoke('enable');
					return form;
				},
				findFirstElement : function(form) {
					var elements = $(form).getElements().findAll(function(element) {
						return 'hidden' != element.type && !element.disabled;
					});
					var firstByIndex = elements.findAll(function(element) {
						return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
					}).sortBy(function(element) {
						return element.tabIndex
					}).first();

					return firstByIndex ? firstByIndex : elements.find(function(element) {
						return /^(?:input|select|textarea)$/i.test(element.tagName);
					});
				},
				focusFirstElement : function(form) {
					form = $(form);
					form.findFirstElement().activate();
					return form;
				},
				request : function(form, options) { form = $(form), options = Object.clone(options || { });

					var params = options.parameters, action = form.readAttribute('action') || '';
					if(action.blank())
						action = window.location.href;
					options.parameters = form.serialize(true);

					if(params) {
						if(Object.isString(params))
							params = params.toQueryParams();
						Object.extend(options.parameters, params);
					}

					if(form.hasAttribute('method') && !options.method)
						options.method = form.method;

					return new Ajax.Request(action, options);
				}
			};

			/*--------------------------------------------------------------------------*/

			Form.Element = {
				focus : function(element) {
					$(element).focus();
					return element;
				},
				select : function(element) {
					$(element).select();
					return element;
				}
			};

			Form.Element.Methods = {

				serialize : function(element) {
					element = $(element);
					if(!element.disabled && element.name) {
						var value = element.getValue();
						if(value != undefined) {
							var pair = { };
							pair[element.name] = value;
							return Object.toQueryString(pair);
						}
					}
					return '';
				},
				getValue : function(element) {
					element = $(element);
					var method = element.tagName.toLowerCase();
					return Form.Element.Serializers[method](element);
				},
				setValue : function(element, value) {
					element = $(element);
					var method = element.tagName.toLowerCase();
					Form.Element.Serializers[method](element, value);
					return element;
				},
				clear : function(element) {
					$(element).value = '';
					return element;
				},
				present : function(element) {
					return $(element).value != '';
				},
				activate : function(element) {
					element = $(element);
					try {
						element.focus();
						if(element.select && (element.tagName.toLowerCase() != 'input' || !(/^(?:button|reset|submit)$/i.test(element.type))))
							element.select();
					} catch (e) {
					}
					return element;
				},
				disable : function(element) {
					element = $(element);
					element.disabled = true;
					return element;
				},
				enable : function(element) {
					element = $(element);
					element.disabled = false;
					return element;
				}
			};

			/*--------------------------------------------------------------------------*/

			var Field = Form.Element;

			var $F = Form.Element.Methods.getValue;

			/*--------------------------------------------------------------------------*/

			Form.Element.Serializers = {
				input : function(element, value) {
					switch (element.type.toLowerCase()) {
						case 'checkbox':
						case 'radio':
							return Form.Element.Serializers.inputSelector(element, value);
						default:
							return Form.Element.Serializers.textarea(element, value);
					}
				},
				inputSelector : function(element, value) {
					if(Object.isUndefined(value))
						return element.checked ? element.value : null;
					else
						element.checked = !!value;
				},
				textarea : function(element, value) {
					if(Object.isUndefined(value))
						return element.value;
					else
						element.value = value;
				},
				select : function(element, value) {
					if(Object.isUndefined(value))
						return this[element.type == 'select-one' ?
						'selectOne' : 'selectMany'](element);
					else {
						var opt, currentValue, single = !Object.isArray(value);
						for(var i = 0, length = element.length; i < length; i++) {
							opt = element.options[i];
							currentValue = this.optionValue(opt);
							if(single) {
								if(currentValue == value) {
									opt.selected = true;
									return;
								}
							} else
								opt.selected = value.include(currentValue);
						}
					}
				},
				selectOne : function(element) {
					var index = element.selectedIndex;
					return index >= 0 ? this.optionValue(element.options[index]) : null;
				},
				selectMany : function(element) {
					var values, length = element.length;
					if(!length)
						return null;

					for(var i = 0, values = []; i < length; i++) {
						var opt = element.options[i];
						if(opt.selected)
							values.push(this.optionValue(opt));
					}
					return values;
				},
				optionValue : function(opt) {
					return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
				}
			};

			/*--------------------------------------------------------------------------*/

			Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
				initialize : function($super, element, frequency, callback) {
					$super(callback, frequency);
					this.element = $(element);
					this.lastValue = this.getValue();
				},
				execute : function() {
					var value = this.getValue();
					if(Object.isString(this.lastValue) && Object.isString(value) ? this.lastValue != value : String(this.lastValue) != String(value)) {
						this.callback(this.element, value);
						this.lastValue = value;
					}
				}
			});

			Form.Element.Observer = Class.create(Abstract.TimedObserver, {
				getValue : function() {
					return Form.Element.getValue(this.element);
				}
			});

			Form.Observer = Class.create(Abstract.TimedObserver, {
				getValue : function() {
					return Form.serialize(this.element);
				}
			});

			/*--------------------------------------------------------------------------*/

			Abstract.EventObserver = Class.create({
				initialize : function(element, callback) {
					this.element = $(element);
					this.callback = callback;

					this.lastValue = this.getValue();
					if(this.element.tagName.toLowerCase() == 'form')
						this.registerFormCallbacks();
					else
						this.registerCallback(this.element);
				},
				onElementEvent : function() {
					var value = this.getValue();
					if(this.lastValue != value) {
						this.callback(this.element, value);
						this.lastValue = value;
					}
				},
				registerFormCallbacks : function() {
					Form.getElements(this.element).each(this.registerCallback, this);
				},
				registerCallback : function(element) {
					if(element.type) {
						switch (element.type.toLowerCase()) {
							case 'checkbox':
							case 'radio':
								Event.observe(element, 'click', this.onElementEvent.bind(this));
								break;
							default:
								Event.observe(element, 'change', this.onElementEvent.bind(this));
								break;
						}
					}
				}
			});

			Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
				getValue : function() {
					return Form.Element.getValue(this.element);
				}
			});

			Form.EventObserver = Class.create(Abstract.EventObserver, {
				getValue : function() {
					return Form.serialize(this.element);
				}
			}); (function() {

				var Event = {
					KEY_BACKSPACE : 8,
					KEY_TAB : 9,
					KEY_RETURN : 13,
					KEY_ESC : 27,
					KEY_LEFT : 37,
					KEY_UP : 38,
					KEY_RIGHT : 39,
					KEY_DOWN : 40,
					KEY_DELETE : 46,
					KEY_HOME : 36,
					KEY_END : 35,
					KEY_PAGEUP : 33,
					KEY_PAGEDOWN : 34,
					KEY_INSERT : 45,

					cache : {}
				};

				var docEl = document.documentElement;
				var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl && 'onmouseleave' in docEl;

				var _isButton;
				if(Prototype.Browser.IE) {
					var buttonMap = {
						0 : 1,
						1 : 4,
						2 : 2
					};
					_isButton = function(event, code) {
						return event.button === buttonMap[code];
					};
				} else if(Prototype.Browser.WebKit) {
					_isButton = function(event, code) {
						switch (code) {
							case 0:
								return event.which == 1 && !event.metaKey;
							case 1:
								return event.which == 1 && event.metaKey;
							default:
								return false;
						}
					};
				} else {
					_isButton = function(event, code) {
						return event.which ? (event.which === code + 1) : (event.button === code);
					};
				}

				function isLeftClick(event) {
					return _isButton(event, 0)
				}

				function isMiddleClick(event) {
					return _isButton(event, 1)
				}

				function isRightClick(event) {
					return _isButton(event, 2)
				}

				function element(event) {
					event = Event.extend(event);

					var node = event.target, type = event.type, currentTarget = event.currentTarget;

					if(currentTarget && currentTarget.tagName) {
						if(type === 'load' || type === 'error' || (type === 'click' && currentTarget.tagName.toLowerCase() === 'input' && currentTarget.type === 'radio'))
							node = currentTarget;
					}

					if(node.nodeType == Node.TEXT_NODE)
						node = node.parentNode;

					return Element.extend(node);
				}

				function findElement(event, expression) {
					var element = Event.element(event);
					if(!expression)
						return element;
					var elements = [element].concat(element.ancestors());
					return Selector.findElement(elements, expression, 0);
				}

				function pointer(event) {
					return {
						x : pointerX(event),
						y : pointerY(event)
					};
				}

				function pointerX(event) {
					var docElement = document.documentElement, body = document.body || {
						scrollLeft : 0
					};

					return event.pageX || (event.clientX + (docElement.scrollLeft || body.scrollLeft) - (docElement.clientLeft || 0));
				}

				function pointerY(event) {
					var docElement = document.documentElement, body = document.body || {
						scrollTop : 0
					};

					return event.pageY || (event.clientY + (docElement.scrollTop || body.scrollTop) - (docElement.clientTop || 0));
				}

				function stop(event) {
					Event.extend(event);
					event.preventDefault();
					event.stopPropagation();

					event.stopped = true;
				}


				Event.Methods = {
					isLeftClick : isLeftClick,
					isMiddleClick : isMiddleClick,
					isRightClick : isRightClick,

					element : element,
					findElement : findElement,

					pointer : pointer,
					pointerX : pointerX,
					pointerY : pointerY,

					stop : stop
				};

				var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
					m[name] = Event.Methods[name].methodize();
					return m;
				});
				if(Prototype.Browser.IE) {
					function _relatedTarget(event) {
						var element;
						switch (event.type) {
							case 'mouseover':
								element = event.fromElement;
								break;
							case 'mouseout':
								element = event.toElement;
								break;
							default:
								return null;
						}
						return Element.extend(element);
					}


					Object.extend(methods, {
						stopPropagation : function() {
							this.cancelBubble = true
						},
						preventDefault : function() {
							this.returnValue = false
						},
						inspect : function() {
							return '[object Event]'
						}
					});

					Event.extend = function(event, element) {
						if(!event)
							return false;
						if(event._extendedByPrototype)
							return event;

						event._extendedByPrototype = Prototype.emptyFunction;
						var pointer = Event.pointer(event);

						Object.extend(event, {
							target : event.srcElement || element,
							relatedTarget : _relatedTarget(event),
							pageX : pointer.x,
							pageY : pointer.y
						});

						return Object.extend(event, methods);
					};
				} else {
					Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__;
					Object.extend(Event.prototype, methods);
					Event.extend = Prototype.K;
				}

				function _createResponder(element, eventName, handler) {
					var registry = Element.retrieve(element, 'prototype_event_registry');

					if(Object.isUndefined(registry)) {
						CACHE.push(element);
						registry = Element.retrieve(element, 'prototype_event_registry', $H());
					}

					var respondersForEvent = registry.get(eventName);
					if(Object.isUndefined(respondersForEvent)) {
						respondersForEvent = [];
						registry.set(eventName, respondersForEvent);
					}

					if(respondersForEvent.pluck('handler').include(handler))
						return false;

					var responder;
					if(eventName.include(":")) {
						responder = function(event) {
							if(Object.isUndefined(event.eventName))
								return false;

							if(event.eventName !== eventName)
								return false;

							Event.extend(event, element);
							handler.call(element, event);
						};
					} else {
						if(!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED && (eventName === "mouseenter" || eventName === "mouseleave")) {
							if(eventName === "mouseenter" || eventName === "mouseleave") {
								responder = function(event) {
									Event.extend(event, element);

									var parent = event.relatedTarget;
									while(parent && parent !== element) {
										try {
											parent = parent.parentNode;
										} catch(e) {
											parent = element;
										}
									}

									if(parent === element)
										return;

									handler.call(element, event);
								};
							}
						} else {
							responder = function(event) {
								Event.extend(event, element);
								handler.call(element, event);
							};
						}
					}

					responder.handler = handler;
					respondersForEvent.push(responder);
					return responder;
				}

				function _destroyCache() {
					for(var i = 0, length = CACHE.length; i < length; i++) {
						Event.stopObserving(CACHE[i]);
						CACHE[i] = null;
					}
				}

				var CACHE = [];

				if(Prototype.Browser.IE)
					window.attachEvent('onunload', _destroyCache);

				if(Prototype.Browser.WebKit)
					window.addEventListener('unload', Prototype.emptyFunction, false);

				var _getDOMEventName = Prototype.K;

				if(!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) {
					_getDOMEventName = function(eventName) {
						var translations = {
							mouseenter : "mouseover",
							mouseleave : "mouseout"
						};
						return eventName in translations ? translations[eventName] : eventName;
					};
				}

				function observe(element, eventName, handler) {
					element = $(element);

					var responder = _createResponder(element, eventName, handler);

					if(!responder)
						return element;

					if(eventName.include(':')) {
						if(element.addEventListener)
							element.addEventListener("dataavailable", responder, false);
						else {
							element.attachEvent("ondataavailable", responder);
							element.attachEvent("onfilterchange", responder);
						}
					} else {
						var actualEventName = _getDOMEventName(eventName);

						if(element.addEventListener)
							element.addEventListener(actualEventName, responder, false);
						else
							element.attachEvent("on" + actualEventName, responder);
					}

					return element;
				}

				function stopObserving(element, eventName, handler) {
					element = $(element);

					var registry = Element.retrieve(element, 'prototype_event_registry');

					if(Object.isUndefined(registry))
						return element;

					if(eventName && !handler) {
						var responders = registry.get(eventName);

						if(Object.isUndefined(responders))
							return element;

						responders.each(function(r) {
							Element.stopObserving(element, eventName, r.handler);
						});
						return element;
					} else if(!eventName) {
						registry.each(function(pair) {
							var eventName = pair.key, responders = pair.value;

							responders.each(function(r) {
								Element.stopObserving(element, eventName, r.handler);
							});
						});
						return element;
					}

					var responders = registry.get(eventName);

					if(!responders)
						return;

					var responder = responders.find(function(r) {
						return r.handler === handler;
					});
					if(!responder)
						return element;

					var actualEventName = _getDOMEventName(eventName);

					if(eventName.include(':')) {
						if(element.removeEventListener)
							element.removeEventListener("dataavailable", responder, false);
						else {
							element.detachEvent("ondataavailable", responder);
							element.detachEvent("onfilterchange", responder);
						}
					} else {
						if(element.removeEventListener)
							element.removeEventListener(actualEventName, responder, false);
						else
							element.detachEvent('on' + actualEventName, responder);
					}

					registry.set(eventName, responders.without(responder));

					return element;
				}

				function fire(element, eventName, memo, bubble) {
					element = $(element);

					if(Object.isUndefined(bubble))
						bubble = true;

					if(element == document && document.createEvent && !element.dispatchEvent)
						element = document.documentElement;

					var event;
					if(document.createEvent) {
						event = document.createEvent('HTMLEvents');
						event.initEvent('dataavailable', true, true);
					} else {
						event = document.createEventObject();
						event.eventType = bubble ? 'ondataavailable' : 'onfilterchange';
					}

					event.eventName = eventName;
					event.memo = memo || { };

					if(document.createEvent)
						element.dispatchEvent(event);
					else
						element.fireEvent(event.eventType, event);

					return Event.extend(event);
				}


				Object.extend(Event, Event.Methods);

				Object.extend(Event, {
					fire : fire,
					observe : observe,
					stopObserving : stopObserving
				});

				Element.addMethods({
					fire : fire,

					observe : observe,

					stopObserving : stopObserving
				});

				Object.extend(document, {
					fire : fire.methodize(),

					observe : observe.methodize(),

					stopObserving : stopObserving.methodize(),

					loaded : false
				});

				if(window.Event)
					Object.extend(window.Event, Event);
				else
					window.Event = Event;
			})(); (function() {
				/* Support for the DOMContentLoaded event is based on work by Dan Webb,
				 Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */

				var timer;

				function fireContentLoadedEvent() {
					if(document.loaded)
						return;
					if(timer)
						window.clearTimeout(timer);
					document.loaded = true;
					document.fire('dom:loaded');
				}

				function checkReadyState() {
					if(document.readyState === 'complete') {
						document.stopObserving('readystatechange', checkReadyState);
						fireContentLoadedEvent();
					}
				}

				function pollDoScroll() {
					try {
						document.documentElement.doScroll('left');
					} catch(e) {
						timer = pollDoScroll.defer();
						return;
					}
					fireContentLoadedEvent();
				}

				if(document.addEventListener) {
					document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
				} else {
					document.observe('readystatechange', checkReadyState);
					if(window == top)
						timer = pollDoScroll.defer();
				}

				Event.observe(window, 'load', fireContentLoadedEvent);
			})();

			Element.addMethods();

			/*------------------------------- DEPRECATED -------------------------------*/

			Hash.toQueryString = Object.toQueryString;

			var Toggle = {
				display : Element.toggle
			};

			Element.Methods.childOf = Element.Methods.descendantOf;

			var Insertion = {
				Before : function(element, content) {
					return Element.insert(element, {
						before : content
					});
				},
				Top : function(element, content) {
					return Element.insert(element, {
						top : content
					});
				},
				Bottom : function(element, content) {
					return Element.insert(element, {
						bottom : content
					});
				},
				After : function(element, content) {
					return Element.insert(element, {
						after : content
					});
				}
			};

			var $continue = new Error('"throw $continue" is deprecated, use "return" instead');

			var Position = {
				includeScrollOffsets : false,

				prepare : function() {
					this.deltaX = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0;
					this.deltaY = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
				},
				within : function(element, x, y) {
					if(this.includeScrollOffsets)
						return this.withinIncludingScrolloffsets(element, x, y);
					this.xcomp = x;
					this.ycomp = y;
					this.offset = Element.cumulativeOffset(element);

					return (y >= this.offset[1] && y < this.offset[1] + element.offsetHeight && x >= this.offset[0] && x < this.offset[0] + element.offsetWidth);
				},
				withinIncludingScrolloffsets : function(element, x, y) {
					var offsetcache = Element.cumulativeScrollOffset(element);

					this.xcomp = x + offsetcache[0] - this.deltaX;
					this.ycomp = y + offsetcache[1] - this.deltaY;
					this.offset = Element.cumulativeOffset(element);

					return (this.ycomp >= this.offset[1] && this.ycomp < this.offset[1] + element.offsetHeight && this.xcomp >= this.offset[0] && this.xcomp < this.offset[0] + element.offsetWidth);
				},
				overlap : function(mode, element) {
					if(!mode)
						return 0;
					if(mode == 'vertical')
						return ((this.offset[1] + element.offsetHeight) - this.ycomp) / element.offsetHeight;
					if(mode == 'horizontal')
						return ((this.offset[0] + element.offsetWidth) - this.xcomp) / element.offsetWidth;
				},
				cumulativeOffset : Element.Methods.cumulativeOffset,

				positionedOffset : Element.Methods.positionedOffset,

				absolutize : function(element) {
					Position.prepare();
					return Element.absolutize(element);
				},
				relativize : function(element) {
					Position.prepare();
					return Element.relativize(element);
				},
				realOffset : Element.Methods.cumulativeScrollOffset,

				offsetParent : Element.Methods.getOffsetParent,

				page : Element.Methods.viewportOffset,

				clone : function(source, target, options) {
					options = options || { };
					return Element.clonePosition(target, source, options);
				}
			};

			/*--------------------------------------------------------------------------*/

			if(!document.getElementsByClassName)
				document.getElementsByClassName = function(instanceMethods) {
					function iter(name) {
						return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
					}


					instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ? function(element, className) {
						className = className.toString().strip();
						var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
						return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
					} : function(element, className) {
						className = className.toString().strip();
						var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
						if(!classNames && !className)
							return elements;

						var nodes = $(element).getElementsByTagName('*');
						className = ' ' + className + ' ';

						for(var i = 0, child, cn; child = nodes[i]; i++) {
							if(child.className && ( cn = ' ' + child.className + ' ') && (cn.include(className) || (classNames && classNames.all(function(name) {
									return !name.toString().blank() && cn.include(' ' + name + ' ');
								}))))
								elements.push(Element.extend(child));
						}
						return elements;
					};
					return function(className, parentElement) {
						return $(parentElement || document.body).getElementsByClassName(className);
					};
				}(Element.Methods);

			/*--------------------------------------------------------------------------*/

			Element.ClassNames = Class.create();
			Element.ClassNames.prototype = {
				initialize : function(element) {
					this.element = $(element);
				},
				_each : function(iterator) {
					this.element.className.split(/\s+/).select(function(name) {
						return name.length > 0;
					})._each(iterator);
				},
				set : function(className) {
					this.element.className = className;
				},
				add : function(classNameToAdd) {
					if(this.include(classNameToAdd))
						return;
					this.set($A(this).concat(classNameToAdd).join(' '));
				},
				remove : function(classNameToRemove) {
					if(!this.include(classNameToRemove))
						return;
					this.set($A(this).without(classNameToRemove).join(' '));
				},
				toString : function() {
					return $A(this).join(' ');
				}
			};

			Object.extend(Element.ClassNames.prototype, Enumerable);

			/*--------------------------------------------------------------------------*/

			function reloadPortal() {
				var obj = window.location.href.toQueryParams();
				var url = null;
				if( typeof (obj) !== 'undefined' && typeof (obj.url) != 'undefined') {
					url = obj.url;
				}
				dispatchDefined = ( typeof (dispatch) !== 'undefined');
				if(dispatchDefined) {
					return dispatch($H({
						controller : 'portal.browser',
						action : "refreshPortal",
						args : [url].toJSON()
					}).toJSON());
				} else {
					alert("no dispatch");
				}
			}
		</script>
	</head>
	<body style="background-color:#CCCCCC">
		<div id="body" style="background-color:#FFFFFF;" class="shadow">
			<div>
				<h2 align="center">Server Currently Unavailable</h2>
				<p style="text-align:center">
					Please try again later.
				</p>
			</div>
			<span id="reload"><a href="javascript:reloadPortal()">refresh</a></span>
		</div>
	</body>
</html>